2010-02-12 7 views
33

simplejson을 사용하여 장고 모델을 직렬화하고 싶습니다. Django의 serializer는 사전을 지원하지 않으며 simplejson은 Django Querysets를 지원하지 않습니다. 이것은 상당히 수수께끼입니다.JSON simplejson으로 장고 모델 직렬화하기

모델에는 스폰서 수준에 외래 키가있는 스폰서가 있습니다. 특정 스폰서 수준에 속한 모든 스폰서를 그룹화하려고합니다. 여기에 목록을 생성하는 코드입니다 :

여기
from django.shortcuts import get_list_or_404 
from special_event.models import Sponsor, SponsorLevel 

sponsor_dict = {} 

roadie_sponsors = get_list_or_404(Sponsor, level__category = SponsorLevel.ROADIE_CHOICE) 

for item in roadie_sponsors: 
    try: 
     sponsor_dict[item.level.name].append(item) 
    except KeyError: 
     sponsor_dict[item.level.name] = [item] 

는 "이 만든"것

{ 
    'Fan': [<Sponsor: Fan Sponsor>], 
    'VIP': [<Sponsor: VIP Sponsor>], 
    'Groupie': [<Sponsor: Groupie Sponsor>], 
    'Silver': [<Sponsor: Silver Sponsor>], 
    'Bronze': [<Sponsor: Another Bronze Sponsor>, <Sponsor: Bronze Sponsor>] 
} 

난 단지 청동을 제외하고, 각 레벨에 하나의 스폰서를 추가 한 번처럼 sponsor_dict 보이는 무엇을, 얼마나 그것을 보여 공장. jQuery가 쉽게 해석 할 수 있도록 JSON에 "모두"가져 오기만하면됩니다. Django의 다른 serializer (XML 또는 YAML과 같은)가 이것을 수행 할 수 있습니까? Django JSON Serializer를 "확장하여 사전을 처리하거나 Django QuerySet 객체를 처리하기 위해"simplejson을 "확장"할 수 있습니까?

답변

39

simplejson으로 연장합니다. 기본적으로 JSON 인코더가 QuerySet을 만날 때 django의 직렬화를 연결하려고합니다. , default 방법에 대한 추가 정보를 원하시면

from json import dumps, loads, JSONEncoder 

from django.core.serializers import serialize 
from django.db.models.query import QuerySet 
from django.utils.functional import curry 

class DjangoJSONEncoder(JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, QuerySet): 
      # `default` must return a python serializable 
      # structure, the easiest way is to load the JSON 
      # string produced by `serialize` and return it 
      return loads(serialize('json', obj)) 
     return JSONEncoder.default(self,obj) 

# partial function, we can now use dumps(my_dict) instead 
# of dumps(my_dict, cls=DjangoJSONEncoder) 
dumps = curry(dumps, cls=DjangoJSONEncoder) 

simplejson documentation를 보라 : 당신은 같은 것을 사용할 수 있습니다. 파이썬 모듈에 넣은 다음 dumps을 가져 오면 좋습니다. 그러나이 함수는 QuerySet 인스턴스를 serialize하는 데 도움이되며 Model 인스턴스는 직접 인스턴스화하지 않습니다.

+1

당신이의 '질문'버튼을 클릭해야 할 질문이있는 경우이 – babonk

10

클레멘트의 대답에 따라 모델을 JSON으로 가져 오려고했습니다.

def toJSON(obj): 
    if isinstance(obj, QuerySet): 
     return simplejson.dumps(obj, cls=DjangoJSONEncoder) 
    if isinstance(obj, models.Model): 
     #do the same as above by making it a queryset first 
     set_obj = [obj] 
     set_str = simplejson.dumps(simplejson.loads(serialize('json', set_obj))) 
     #eliminate brackets in the beginning and the end 
     str_obj = set_str[1:len(set_str)-2] 
    return str_obj 
+0

매우 영리하다 발견 사용하는 것입니다 맨 위 오른쪽. '귀하의 답변'양식은 답변을 게시하는 데 사용됩니다. – Pickels

+13

사과드립니다. 주된 대답은 객체를 직렬화 할 수 없다는 점에주의를 기울이기 때문에 주제를 보완하기 위해서였습니다. 코드가 작동하기 때문에이 목표를 달성 할 수 있습니다. 좋은 아이디어 또는 나쁜 사람에 대한 내 질문은 더 나은 통합에 대한 토론을 초대하려는 의도 였고, 분명히 아무도 경멸하지 않았습니다. – jcage

13

A는 장고에 가장 구조를 직렬화 정말 유연한 방법은 시리얼 클래스는 here

+1

방금 ​​구현했습니다. 그것은 훌륭합니다! 이 스크립트는 더 많은 인정을받을 자격이 있습니다. – Glycerine

+1

+1 - 이것은 나에게도 아주 잘 돌아갔다. – RyanBrady

+0

이것은 매우 간단하고 적응 가능한 솔루션입니다. – stormlifter