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
不过这情况有点棘手,因为当循环无法解包迭代器的项目时,模板不会抛出任何运行时错误。
3 个回答
3
在 Django 模板中使用 defaultdict 时要 非常 小心,我看到你在代码中确实用了 defaultdict
。
因为在模板里,它们的表现并不像你想的那样正常,这主要是因为 Django 访问属性和其他内容的方式。解决这个问题的唯一办法就是把它们转换成普通的字典:
context['dictstructure'] = dict(mydefaultdict)
关于这个问题,模板文档 在处理了第16335号问题后进行了更新,特别提到了这个问题。
从技术上讲,当模板系统遇到一个点(.)时,它会按以下顺序进行查找:
- 字典查找
- 属性查找
- 方法调用
- 列表索引查找
这可能会导致一些意想不到的行为,特别是对于那些重写了字典查找的对象。例如,考虑以下代码片段,它试图遍历一个 collections.defaultdict:
{% for k, v in defaultdict.iteritems %} Do something with k and v here... {% endfor %}
因为字典查找是第一个进行的,所以它会优先执行,提供一个默认值,而不是使用你想要的 .iteritems() 方法。在这种情况下,建议你先把它转换成一个普通的字典。
4
把你的for循环更新成这样:
{% for log in log_group.itervalues %}
或者,如果你确实需要用到 key
(你的示例模板里没有显示你在用它):
{% for key, log in log_group.iteritems %}
9
将
{% for key, log in log_group %}
改成
{% for key, log in log_group.items %}