JSON Сериализация моделей Django с помощью simplejson - PullRequest
33 голосов
/ 12 февраля 2010

Я бы хотел использовать simplejson для сериализации модели Django. Сериализатор Django не поддерживает словари ... и simplejson не поддерживает наборы запросов Django. Это довольно загадка.

В модели есть спонсоры, которые имеют внешний ключ для уровня спонсора, я пытаюсь сгруппировать всех спонсоров, принадлежащих к определенному уровню спонсора. Вот код, который генерирует список:

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]

Вот как выглядит sponsor_dict, как только он "сделан"

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

Я добавил только одного спонсора на каждом уровне, кроме бронзы, просто чтобы показать, как это работает. Все, что я хочу сделать, это вставить все в JSON, чтобы jQuery мог легко его интерпретировать. Могут ли другие сериализаторы Django (такие как XML или YAML) достичь этого? Могу ли я «расширить» Django JSON Serializer для обработки словарей или «расширить» simplejson для обработки объектов Django QuerySet?

Ответы [ 3 ]

39 голосов
/ 12 февраля 2010

Я бы пошел с расширением simplejson . По сути, вы хотите подключить сериализацию django, когда кодировщик JSON обнаруживает QuerySet. Вы можете использовать что-то вроде:

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)

Для получения дополнительной информации о default методе, посмотрите simplejson документацию . Поместите это в модуль Python, затем импортируйте dumps и все готово. Но учтите, что эта функция поможет вам только сериализовать QuerySet экземпляров, а не Model напрямую.

13 голосов
/ 03 июля 2011

Действительно гибкий способ сериализации большинства структур в django - использовать найденный класс сериализатора здесь

10 голосов
/ 15 августа 2010

основываясь на ответе Клемента, я сделал это, чтобы получить модели и в 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
...