2013-04-08 10 views
15

मैं अपने क्वेरीसमूह को क्रमानुसार करना चाहते हैं के रूप में क्वेरीसमूह, और मैं इस दृश्य आउटपुट के रूप में एक प्रारूप में हैं:आउटपुट Django JSON

class JSONListView(ListView): 
    queryset = Users.objects.all() 

    def get(self, request, *args, **kwargs): 
     return HttpResponse(json.dumps({'data': [['bar','foo','bar','foo'],['foo','bar','foo','bar']]}, indent=4), content_type='application/json') 

मैं बस पता नहीं कैसे उत्पादन मैनुअल डेटा की बजाय क्वेरीसमूह के लिए उदाहरण में

मैं

json.dumps({"data": self.get_queryset()}) 

और

serializers.serialize("json", {'data': self.get_queryset()}) 

की कोशिश की है, लेकिन यह अभ्यस्त काम करते हैं। मैं क्या गलत कर रहा हूं? क्या मुझे कस्टम JSON एन्कोडर बनाने की आवश्यकता है?

+0

क्या काम नहीं किया? क्या आपने पढ़ा है [serialising क्वेरीसेट पर दस्तावेज़] (https://docs.djangoproject.com/en/dev/topics/serialization/)? मुझे लगता है कि समस्या आपके मॉडल –

उत्तर

24

यह काम नहीं किया, क्योंकि QuerySets JSON serializable नहीं हैं।

1) json.dumps के मामले में आप स्पष्ट रूप से JSON serializable ऑब्जेक्ट में अपने क्वेरीसमूह कन्वर्ट करने के लिए है:

class Model(model.Model): 
    def as_dict(self): 
     return { 
      "id": self.id, 
      # other stuff 
     } 

और क्रमबद्धता:

dictionaries = [ obj.as_dict() for obj in self.get_queryset() ] 
return HttpResponse(json.dumps({"data": dictionaries}), content_type='application/json') 

2) serializers के मामले में। Serializers या तो JSON serializable ऑब्जेक्ट या QuerySet स्वीकार करते हैं, लेकिन एक QuerySet युक्त एक शब्दकोश न तो है। इस प्रयास करें:

serializers.serialize("json", self.get_queryset()) 

इसके बारे में और अधिक पढ़ें यहाँ:

https://docs.djangoproject.com/en/dev/topics/serialization/

+0

के भीतर विदेशीके/एम 2 एम संबंधों के साथ है यह एक अच्छा जवाब है। मैं पहले समाधान के साथ जाऊंगा। आपके दूसरे समाधान में, डेटा को 'कुंजी' असाइन करना कैसे संभव है? क्या यह {"डेटा" जैसा होना चाहिए: serializers.serialize ("json", self.get_queryset())}? – user2232982

+1

@ user2232982 मैं ईमानदार होने के लिए निश्चित नहीं हूं, मैं हमेशा पहली तकनीक का उपयोग कर रहा हूं। :) आपका समाधान अच्छा नहीं है, क्योंकि आपको JSON स्ट्रिंग के साथ एक शब्दकोश मिलता है, इसलिए आपको इसे क्रमबद्ध करने की आवश्यकता होती है जिसके परिणामस्वरूप डबल सीरियलाइज्ड ऑब्जेक्ट होता है। : ओ – freakish

+0

पहला तहनीक पहिया का आविष्कार है। – Alex78191

13

सरल उदाहरण:

from django.http import JsonResponse 

def some_view(request): 
    data = list(SomeModel.objects.values()) 
    return JsonResponse(data, safe=False) # or JsonResponse({'data': data}) 

या किसी अन्य दृष्टिकोण:

from django.core import serializers 
from django.http import HttpResponse 

def some_view(request): 
    qs = SomeModel.objects.all() 
    qs_json = serializers.serialize('json', qs) 
    return HttpResponse(qs_json, content_type='application/json') 

इस में मामले प्रतिक्रिया बिट (डिफ़ॉल्ट रूप से मांगपत्र के बिना) अलग होगा:

[ 
    { 
     "model": "some_app.some_model", 
     "pk": 1, 
     "fields": { 
      "name": "Ivan", 
      "age": 35, 
      ... 
     } 
    }, 
    ... 
] 

मुझे कहना पड़ेगा कि यह वस्तु क्रमांकन के लिए marshmallow की तरह कुछ का उपयोग करने के अच्छी आदत है।

और वहाँ कुछ नोट कैसे बेहतर प्रदर्शन के लिए जितनी जल्दी संभव के रूप में अपने दृष्टिकोण को बनाने के लिए कर रहे हैं:

  • उपयोग पृष्ठांकन अगर आपके क्वेरीसमूह बड़ा है;
  • सीरियलाइजेशन से बचने और क्लाइंट अनावश्यक मॉडल के फ़ील्ड को भेजने के लिए आवश्यक फ़ील्ड की सूची निर्दिष्ट करने के लिए objects.values() का उपयोग करें (आप fields से serializers.serialize पर भी पास कर सकते हैं);
  • उपयुक्त settings.CONN_MAX_AGE सेट करें, उदाहरण के लिए 500 (उसकेोकू दस्तावेज़ से मूल्य);
  • आप बेहतर प्रदर्शन के लिए फ़ंक्शन आधारित दृश्य का उपयोग कर सकते हैं (लेकिन स्पष्ट कोड स्पष्ट रूप से थोड़ा तेज कोड से बेहतर है, सावधान रहें);
+0

JSON के साथ 'JsonResponse' का उपयोग करना गलत है, इसके बजाय' HttpResponse' का उपयोग किया जाना चाहिए। यदि – Alex78191

+0

का उपयोग करना है तो मुझे विशिष्ट फाइलों के साथ Django मॉडल प्रारूप पसंद नहीं है '{model:" name.sub ", pk: 1, फ़ील्ड: {, ...}}'। मुझे [अपने JS फ़ील्ड के साथ सरल JSON] पसंद है [https://stackoverflow.com/a/30243413/4854931)। – Alex78191

+0

@ Alex78191 धन्यवाद, आप सही हैं। मुझे उम्मीद थी कि डीजेगो के सीरियलाइज़र डीआरएफ धारावाहिकों के समान ही काम करेंगे। –

0

इस प्रयास करें:

class JSONListView(ListView): 
    queryset = Users.objects.all() 


    def get(self, request, *args, **kwargs): 
     data = {} 
     data["users"] = get_json_list(queryset) 
     return JSONResponse(data) 


def get_json_list(query_set): 
    list_objects = [] 
    for obj in query_set: 
     dict_obj = {} 
     for field in obj._meta.get_fields(): 
      try: 
       if field.many_to_many: 
        dict_obj[field.name] = get_json_list(getattr(obj, field.name).all()) 
        continue 
       dict_obj[field.name] = getattr(obj, field.name) 
      except AttributeError: 
       continue 
     list_objects.append(dict_obj) 
    return list_objects 
+0

मूल समस्या और समाधान का उपयोग किए बिना कोड देने और दूसरों के लिए नौकरी करने के लिए, बहुत मदद नहीं करता है ... – matteeyah

0

लक्ष्य एक API कि आप JSON प्रारूप में अपने मॉडल का उपयोग करने की अनुमति देते हैं मैं तुम्हें django-restframework Django के भीतर एक अत्यधिक लोकप्रिय पैकेज है कि उपयोग करने के लिए सलाह देते हैं निर्माण करने के लिए है, तो इस प्रकार के कार्यों को प्राप्त करने के लिए समुदाय।

यह पृष्ठांकन, डिफाइनिंग serializers, नेस्टेड मॉडल/संबंधों और अधिक के रूप में उपयोगी सुविधाओं में शामिल हैं। यहां तक ​​कि यदि आप केवल मामूली जावास्क्रिप्ट कार्यों और अजाक्स कॉल करना चाहते हैं, तो भी मैं आपको जेएसओएन प्रतिक्रिया को मैन्युअल रूप से परिभाषित करने के बजाय Django Rest Framework का उपयोग करके उचित API बनाने का सुझाव दूंगा।

संबंधित मुद्दे