2010-02-12 8 views
33

Chciałbym użyć simplejson do serializacji modelu Django. Serializer Django nie obsługuje słowników ... a simplejson nie obsługuje Django Querysets. To dość zagadka.JSON Serializing Django Models with simplejson

W modelu są sponsorzy, którzy mają klucz obcy na poziomie sponsora, staram się pogrupować wszystkich sponsorów należących do określonego poziomu sponsora. Oto kod, który generuje listę:

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] 

oto co sponsor_dict wygląda po jego „made”

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

ja tylko dodaje jeden sponsora na każdym poziomie, z wyjątkiem brązu, żeby pokazać, jak go Prace. Wszystko, co chcę zrobić, to uzyskać "wszystko" w JSON, aby jQuery mógł je łatwo zinterpretować. Czy inne serializery Django (takie jak XML lub YAML) mogą to osiągnąć? Czy mogę "rozszerzyć" Serializer JSON Django do obsługi słowników lub "rozszerzyć" simplejson do obsługi obiektów Django QuerySet?

Odpowiedz

39

Zostałbym rozszerzony o simplejson. Zasadniczo, chcesz podłączyć serializację django, gdy enkoder JSON napotka kwerendy. Można użyć coś takiego:

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) 

Aby uzyskać więcej informacji na default metodzie spojrzeć simplejson documentation. Umieść to w module Pythona, a następnie zaimportuj dumps i możesz już iść. Należy jednak pamiętać, że ta funkcja pomoże tylko szeregować instancje instancji QuerySet, a nie instancji Model.

+1

to bardzo mądry – babonk

10

w oparciu o odpowiedź Klemensa, zrobiłem to, aby uzyskać modele również w 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

Jeśli masz pytanie, trzeba kliknąć przycisk „zapytać pytanie” w w prawym górnym rogu. Formularz "Twoja odpowiedź" służy do publikowania odpowiedzi. – Pickels

+13

Moje przeprosiny. Chciałem tylko uzupełnić temat, ponieważ główna odpowiedź zwraca uwagę na niezdolność do serializowania obiektów. Ten cel został osiągnięty, ponieważ kod działa. Moje pytanie o to, że jest dobrym lub złym pomysłem, miało zachęcić do dyskusji na temat lepszej integracji, a na pewno nikomu nie gardzić. – jcage

13

Naprawdę elastyczny sposób serializacji większość struktur w Django jest użycie klasy serializer znaleźć here

+1

Właśnie to zaimplementowałem. To znakomicie! Ten skrypt zasługuje na większe uznanie. – Glycerine

+1

+1 - To też zadziałało bardzo dobrze. – RyanBrady

+0

To bardzo proste i elastyczne rozwiązanie. – stormlifter

Powiązane problemy