我是Django的新手,我正在使用1.5版来构建REST api。调用api期望返回JSON(我在Ember.js前端使用它。)
我想知道我不能做这样的事情:
def listproject(request, pk_id):
# list single project at /projects/<pk_id>
project = Project.objects.get(pk = pk_id)
snapshots = Snapshot.objects.filter(project = project)
# (both are same up to here)
return render_to_response('project.json',
{"project":project, "snapshots":snapshots},
mimetype="text/json")
这个Django模板project.json
的位置:
{
"id": "{{ project.pk }}",
"name": "{{ project.name }}",
"snapshot_ids": [ {% for snapshot in snapshots %}"{{ snapshot.pk }}"{% if not forloop.last %}, {% endif %}{% endfor %}
}
与Django合作的人比我长得多,这表明使用模板效率低下。他建议我做以下事情:
def listproject(request, pk_id):
# list single project at /projects/<pk_id>
project = Project.objects.get(pk = pk_id)
snapshots = Snapshot.objects.filter(project = project)
# (both are same up to here)
ret_json = []
ret_json.append('{"id": "' + str(project.pk) + '", ')
ret_json.append('"name": "' + project.name + '", "snapshot_ids": [')
snapshot_json = []
for snapshot in snapshots:
snapshot_json.append('"' + str(snapshot.pk) + '",')
ret_json.append(''.join(snapshot_json)[0:-1] + ']}')
return HttpResponse(content=''.join(ret_json), mimetype="text/json")
我已经测试了两者。虽然我的版本产生了更多可读的JSON,但它们的工作方式相同。
请帮助我们结束辩论!哪个更有效(以及为什么)?
答案 0 :(得分:3)
Django模板确实效率不高。但是,当您拥有非常大的模板本身扩展或包含许多其他模板(例如在复杂的内容管理系统中)时,这才是真正的问题。使用包含少量字段的单个模板,与提供请求的总体开销相比,模板呈现无关紧要。
那说我对你的两种选择都有些困惑。为什么不通过标准json
库生成JSON?这是正确的方法,而不是在模板或Python代码中构建字符串。
ret = {'id': project.id,
'name': project.name,
'snapshot_ids': [snapshot.id for snapshot in snapshots]}
ret_json = json.dumps(ret)
答案 1 :(得分:2)
这两个选项对我来说都很糟糕。我宁愿避免尽可能“手写”JSON并直接从Python数据结构转换。
幸运的是json
模块就是为此设计的。
import json
def listproject(request, pk_id):
# list single project at /projects/<pk_id>
project = Project.objects.get(pk=pk_id)
snapshots = Snapshot.objects.filter(project=project)
data = {
"id": project.pk,
"name": project.name,
"snapshot_ids": [snapshot.pk for snapshot in snapshots],
}
return HttpResponse(content=json.dumps(data), mimetype="text/json")
避免“手写”代码的原因很明显 - 避免错别字,代码更短更简单,json模块可能更快。
如果您担心生成的JSON的“可读性”,json模块会提供一些控制输出的选项(缩进等):
http://docs.python.org/2/library/json.html
答案 2 :(得分:0)
我通常使用这个小功能:
import json
from django.http import HttpResponse
def json_response(ob):
return HttpResponse(
json.dumps(ob), mimetype="application/json")
那么你可以从视图中返回结果:
def listproject(request, pk_id):
project = Project.objects.get(pk=pk_id) # Use get_object_or_404 ?
snapshots = Snapshot.objects.filter(project=project)
return json_response({
"id": project.pk,
"name": project.name,
"snapshot_ids": [snapshot.pk for snapshot in snapshots],
})