2011-06-21 70 views
4

我不確定爲什麼這個模板沒有渲染任何內容到頁面。 有什麼明顯的我在這裏失蹤?在Django模板中使用詞典的循環問題

查看:

@user_passes_test(is_staff) 
def details_activity_log(request, project_id, template='projects/details_activity_log.html'): 

    project = get_object_or_404(Project.objects.select_related(), pk=project_id) 
    action_log = project.projectactionlog_set.all() 

    log_group = defaultdict(list) 

    for log in action_log: 
     log_group[log.action_time.strftime('%y%m%d')].append(log) 


    #import pdb; pdb.set_trace() 

    return render_to_response(template, { 
     'log_group' : log_group, 
     'project' : project, 
     'action_log' : action_log, 
     'tab_5'  : 'active', 
    }, context_instance=RequestContext(request)) 

log_group包含字典模型對象,像這樣:

defaultdict(<type 'list'>, {'110614': [<ProjectActionLog: ProjectActionLog object>, ...]}) 

模板:

{% for key, log in log_group %} 
     {% for action in log %} 
     {{ action }} 
     {{ action.action_time }}      
     {{ action.user.first_name }} 
     {{ action.message }} 
     {{ action.object_name }} 
     {% endfor %} 
    {% endfor %} 

編輯 如果我已經看過文檔,我會看到答案。 https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for

但是,這是一個棘手的情況,因爲當循環無法解壓迭代器項目時,模板不會拋出任何運行時錯誤。

+0

您使用的是'defaultdict',小心!看到我的答案如下或http://stackoverflow.com/questions/4764110/django-template-cant-loop-defaultdict – Stefano

回答

5

變化

{% for key, log in log_group %} 

{% for key, log in log_group.items %} 
+3

更好:'log_group.iteritems'。但在這種情況下,它看起來並不像他使用'key',所以'itervalues'應該這樣做。 –

+0

你能解釋爲什麼這是?從一點搜索我收集iteritems是一個發電機,並延遲加載項目佔用較少的內存?那是對的嗎? – Keyo

+0

他是正確的使用iter *方法通常更好。副作用是,如果你需要不止一次地循環使用dict,通常只需將它加載到內存中(除非它很大)。如果你的字典是相當小的話,那麼兩者之間的差異在個人基礎上可以忽略不計。 – John

4

更新您的for循環:

{% for log in log_group.itervalues %} 

或者,如果你確實需要key(你的例子模板不會使用你展示它):

{% for key, log in log_group.iteritems %} 
3

而且是非常小心在Django模板defaultdicts,我在你的代碼中看到的,你確實使用defaultdict

由於django試圖訪問屬性/屬性/等方式,它們在模板內顯然不能正常工作。唯一的解決辦法是將它們轉換爲類型的字典:

context['dictstructure'] = dict(mydefaultdict) 

template documentation打補丁,以下ticket #16335changeset包括關於這個問題的特別通知。

技術上,當模板系統遇到 點,它會嘗試以下查找,順序如下:

  • 字典查找
  • 屬性查找
  • 方法調用
  • 列表 - 索引查詢

這可以導致一些意想不到的行爲,其中的對象會覆蓋 字典查找。例如,請考慮以下代碼段 ,該代碼段試圖循環訪問集合。defaultdict:

{% for k, v in defaultdict.iteritems %} 
    Do something with k and v here... 
{% endfor %} 

由於字典查找首先發生,該行爲踢,並提供默認值 代替使用預定.iteritems()方法。在這種情況下, 首先考慮轉換爲字典。

另請參見問題Django template can't loop defaultdict

+0

感謝您的defaultdict趕上! – IMFletcher