JSON 使用 simplejson 序列化 Django 模型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2249792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSON Serializing Django Models with simplejson
提问by Zack
I'd like to use simplejson to serialize a Django model. Django's serializer doesn't support dictionaries... and simplejson doesn't support Django Querysets. This is quite a conundrum.
我想使用 simplejson 来序列化 Django 模型。Django 的序列化程序不支持字典……并且 simplejson 不支持 Django 查询集。这是一个难题。
In the model there's sponsors that have a Foreign Key to sponsor level, I'm trying to group all the sponsors that belong to a certain sponsor level together. Here's the code that generates the 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]
Here's what sponsor_dictlooks like once it's "made"
这是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>]
}
I only added one sponsor in each level, except for bronze, just to show how it works. All I want to do is get it "all" into JSON so jQuery can interpret it easily. Can Django's other serializers (like XML or YAML) accomplish this? Can I "extend" the Django JSON Serializer to handle dictionaries or "extend" simplejson to handle Django QuerySet objects?
我只在每个级别添加了一个赞助商,除了铜牌,只是为了展示它是如何运作的。我想要做的就是将它“全部”放入 JSON 中,以便 jQuery 可以轻松解释它。Django 的其他序列化程序(如 XML 或 YAML)能做到这一点吗?我可以“扩展” Django JSON Serializer 以处理字典或“扩展” simplejson 以处理 Django QuerySet 对象吗?
回答by Clément
I would go with extending simplejson. Basically, you want to plug in django's serialization when the JSON encoder encounters a QuerySet. You could use something like:
我会去扩展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)
For more info on defaultmethod, have a look at simplejson documentation. Put that in a python module, then import dumpsand you're good to go. But note that this function will only help you serializing QuerySetinstances, not Modelinstances directly.
有关default方法的更多信息,请查看simplejson 文档。把它放在一个 python 模块中,然后导入dumps,你就可以开始了。但请注意,此功能只会帮助您序列化QuerySet实例,而不是Model直接实例化。
回答by selaux
回答by jcage
based on Clement's answer, I did this to get models into JSON as well.
根据 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

