2013-04-08 3 views
15
내의 검색어를 직렬화 할

로의 검색어, 나는이보기 출력과 같은 형식으로 원하는 :출력 장고 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

무엇이 작동하지 않습니까? [시리얼 라이 제이션 쿼리 세트] (https://docs.djangoproject.com/en/dev/topics/serialization/)를 읽으셨습니까? 나는 문제가 귀하의 모델 내 ForeignKey/M2M 관계에 있다고 생각합니다. –

답변

24

QuerySet이 JSON을 직렬화 할 수 없기 때문에 작동하지 않았습니다. json.dumps의 경우

1) 당신은 명시 적으로 JSON 직렬화 객체에 검색어 세트를 변환 할 수 있습니다

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는 JSON 직렬화 가능 객체 또는 QuerySet을 허용하지만 QuerySet을 포함하는 사전은 어느 것도 아니다. 이 시도 :

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

여기에 대해 자세히 알아보기 :

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

+0

그것은 좋은 대답입니다. 나는 첫 번째 해결책을 가지고 갈 것이다. 두 번째 솔루션에서는 '키'를 데이터에 어떻게 할당 할 수 있습니까? { "data": serializers.serialize ("json", self.get_queryset())}와 같아야합니까? – user2232982

+1

@ user2232982 솔직히 말하면, 나는 항상 첫 번째 기술을 사용하고 있습니다. :) JSON 문자열이있는 사전을 얻었으므로 솔루션이 좋지 않습니다. 그래서 여전히 직렬화해야하므로 이중 직렬화 된 객체가됩니다. : O – 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()을 사용하여 직렬화를 피하고 클라이언트가 불필요한 모델의 필드로 보내는 데 필요한 필드 목록을 지정하십시오 (fieldsserializers.serialize으로 전달할 수도 있음).
  • 이 적절하게 설정된다. settings.CONN_MAX_AGE, 예를 들면, 500 (heroku 문서들로부터의 값);
  • 더 나은 성능을 위해 함수 기반보기를 사용할 수 있습니다 (그러나 명확한 코드는 약간 더 빠른 코드보다 낫습니다).
+0

JSON과 함께'JsonResponse'를 사용하는 것은 올바르지 않습니다. 대신'HttpResponse'가 사용되어야합니다. – Alex78191

+0

을 사용하는 경우 특정 fileds {{model : "name.sub", pk : 1, fields : {, ...}}'가있는 장고 모델 형식을 좋아하지 않습니다. 나는 [자체 필드가있는 간단한 JSON] (https://stackoverflow.com/a/30243413/4854931)을 좋아한다. – Alex78191

+0

@ Alex78191 감사합니다. 당신 말이 맞습니다. 장고의 시리얼 라이저는 DRF 시리얼 라이저와 같은 방식으로 작동 할 것으로 예상됩니다. –

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

을 목표 난 당신이 장고 내에서 엄청난 인기 패키지 인 django-restframework를 사용하는 것이 좋습니다 당신은 JSON 형식으로 모델에 액세스 할 수 있도록 API를 구축하는 경우 커뮤니티에서 이러한 유형의 작업을 수행 할 수 있습니다.

  • Django Rest Framework Website
  • Github
  • 그것은 같은 매김, 정의 직렬 변환기, 중첩 된 모델/관계 등과 같은 유용한 기능을 포함

      . JSUB 응답을 수동으로 정의하는 대신 Django Rest Framework를 사용하여 적절한 API를 작성하는 것이 좋습니다.