Django模板中字典的循环问题

5 投票
3 回答
3431 浏览
提问于 2025-04-16 19:58

我不太明白为什么这个模板没有在页面上显示任何内容。这里面有没有什么明显的地方我忽略了呢?

视图:

@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() 方法。在这种情况下,建议你先把它转换成一个普通的字典。

请查看问题 Django 模板无法遍历 defaultdict

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 %}

撰写回答