我应该担心Django模板效率低下吗?

时间:2014-01-09 20:29:31

标签: python django json django-templates ember-data

我是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,但它们的工作方式相同。

请帮助我们结束辩论!哪个更有效(以及为什么)?

3 个答案:

答案 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],
    })