2014-01-09 41 views
0

我對Django比較新,我使用1.5版來構建REST api。調用api需要返回JSON(我使用Ember.js前端)。我應該擔心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) 

    return render_to_response('project.json', 
    {"project":project, "snapshots":snapshots}, 
    mimetype="text/json") 

哪裏project.json是這樣的Django模板:

{ 
    "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。

請幫助我們結束辯論!哪個更有效率(以及爲什麼)?

+1

爲什麼你要問大約只有efficency?這不是唯一的標準(你寫Python,你開始比必要慢幾倍!)。如何輕鬆寫作並改變它?可理解性呢? – delnan

+0

好點!儘管這是針對生產代碼的,但它的要求更爲嚴格。 Daniel和Anentropic的答案變得更容易編寫,改變和理解,除了做「正確的方式」之外。優點四周! – nickiaconis

回答

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) 
+0

''snapshot_ids':[快照。快照中的快照ID]'我不熟悉這種語法。供參考:[list comprehensions](http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions)。 – nickiaconis

+0

現在看起來如此明顯,但我發誓它不是那麼好!謝謝你的回答丹尼爾!列表解析可以再次用來製作一個項目數組版本。避免字符串黑客感覺很好=) – nickiaconis

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

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], 
    }) 
相關問題