在django模板中循环遍历DefaultDict时出现奇怪的运行时错误

时间:2015-01-16 13:58:10

标签: python django

使用Django 1.5.1

我这里有一个简单的代码 -

count_by_media_type = defaultdict(int)
for user_media in user_media_data:
    count_by_media_type[user_media['media_type']] += 1

这是视图的一部分,使用for迭代循环在模板中呈现 -

{% for media_type in count_by_media_type %}
    ..........
{% endfor %}

循环中count_by_media_type方法之前的render_to_response的值是 defaultdict(<type 'int'>, {u'photo': 1, u'audio': 4, u'video': 3})

但不知何故,在渲染时,迭代中存在运行时错误

dictionary changed size during iteration

在模板上下文中看到的count_by_media_type的值变为

defaultdict(<type 'int'>, {u'photo': 1, u'audio': 4, u'video': 3, u'media_type': 0})

这很奇怪,因为新密钥media_type如何进入变量?

现在,当我切换上面的代码时,在视图中提到

count_by_media_type = Counter([user_media['media_type'] for user_media in user_media_data])

一切正常。

有人提出任何线索吗?

1 个答案:

答案 0 :(得分:4)

使用defaultdict会导致Django模板中的奇怪行为,因为模板变量查找的工作方式。请参阅Django docs幕后花絮框。

Django文档建议在传递给模板之前将defaultdict转换为常规dict

count_by_media_type = defaultdict(int)
for user_media in user_media_data:
    count_by_media_type[user_media['media_type']] += 1

count_by_media_type = dict(count_by_media_type)

或者,as this answer suggests,您可以在插入值后禁用默认功能。

count_by_media_type.default_factory = None