JSON使用simplejson序列化Django模型

时间:2010-02-12 05:07:20

标签: django json serialization django-queryset

我想使用simplejson来序列化Django模型。 Django的序列化程序不支持字典...而simplejson不支持Django Querysets。这是一个相当难的问题。

在模型中,赞助商有赞助级别的外键,我试图将属于某个赞助商级别的所有赞助商组合在一起。这是生成列表的代码:

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 个答案:

答案 0 :(得分:39)

我会继续扩展 simplejson 。基本上,当JSON编码器遇到QuerySet时,您希望插入django的序列化。你可以使用类似的东西:

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 documentation。把它放在python模块中,然后导入dumps,你就可以了。但请注意,此函数仅帮助您直接序列化QuerySet个实例,而不是Model个实例。

答案 1 :(得分:13)

在django中序列化大多数结构的一种非常灵活的方法是使用找到的序列化程序类here

答案 2 :(得分:10)

根据Clement的回答,我这样做也是为了让模型进入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