django:控制json序列化
在Django中,有没有办法控制json的序列化?下面这段简单的代码会返回一个json格式的对象:
co = Collection.objects.all()
c = serializers.serialize('json',co)
生成的json大概是这样的:
[
{
"pk": 1,
"model": "picviewer.collection",
"fields": {
"urlName": "architecture",
"name": "\u0413\u043e\u0440\u043e\u0434 \u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430",
"sortOrder": 0
}
},
{
"pk": 2,
"model": "picviewer.collection",
"fields": {
"urlName": "nature",
"name": "\u041f\u0440\u0438\u0440\u043e\u0434\u0430",
"sortOrder": 1
}
},
{
"pk": 3,
"model": "picviewer.collection",
"fields": {
"urlName": "objects",
"name": "\u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0438 \u043d\u0430\u0442\u044e\u0440\u043c\u043e\u0440\u0442",
"sortOrder": 2
}
}
]
你可以看到,它以一种方式序列化数据,让你可以在需要的时候重新创建整个模型——这没问题,但对于我来说,这样的格式在简单的JS ajax中不太方便:我想尽量减少数据流量,让整个过程更清晰。
我做的事情是创建了一个视图,把对象传递给一个.json模板,然后这个模板会生成更“好看”的json输出,像这样:
[
{% if collections %}
{% for c in collections %}
{"id": {{c.id}},"sortOrder": {{c.sortOrder}},"name": "{{c.name}}","urlName": "{{c.urlName}}"}{% if not forloop.last %},{% endif %}
{% endfor %}
{% endif %}
]
这样做是有效的,输出的结果看起来好多了:
[
{
"id": 1,
"sortOrder": 0,
"name": "Город и архитектура",
"urlName": "architecture"
},
{
"id": 2,
"sortOrder": 1,
"name": "Природа",
"urlName": "nature"
},
{
"id": 3,
"sortOrder": 2,
"name": "Объекты и натюрморт",
"urlName": "objects"
}
]
不过,我有点担心我的解决方案使用了模板(这增加了处理的步骤,可能会影响性能),而且如果我更新模型的话,还需要手动维护。
我在想,json的生成应该是模型的一部分(如果我错了请纠正我),应该用原生的python-json和Django的实现来完成,但我不知道怎么去掉我不想要的部分。
还有一点,即使我限制了要序列化的字段,它的id总是会在元素容器外面显示,而是以“pk”的形式呈现。
4 个回答
0
与其自己写代码,不如让Piston来帮你把Django模型转换成JSON格式。默认情况下,它只会把模型的字段转换,不会包含额外的信息。而且你可以很简单地选择要包含或排除哪些字段,甚至是相关的字段。这样就不需要额外的模板,代码也很少。
2
我建议你使用json库来编码你的数据,而不是自己手动构造类似json的字符串。上面的代码似乎没有正确处理转义字符,这就是一个问题。而自己写序列化程序其实没什么好处,反而容易出错。
2
这真的很简单。给你一个快速的例子:
from django.http import HttpResponse
from django.utils import simplejson
def simple_view(request):
response = {'string': "test",
'number': 42,
'array': [1, 2, 3],
'js_object': dict(foo="bar")}
return HttpResponse(simplejson.dumps(response),
mimetype="application/json")
这个视图会返回以下内容的等价JSON:
{"string": "test",
"number": 42,
"array": [1, 2, 3],
"js_object": {foo: "bar"}}
补充一下:没错,Assaf Lavie说得对,你的模板可能会输出无效的JSON。