在 Django 模板中循环 DefaultDict 时出现奇怪的运行时错误
Weird runtime error when looping over DefaultDict in django template
使用 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 %}
循环中render_to_response
方法之前count_by_media_type
的值是
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])
一切正常。
有任何线索吗?
使用 defaultdict
s 会导致 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
使用 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 %}
循环中render_to_response
方法之前count_by_media_type
的值是
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])
一切正常。
有任何线索吗?
使用 defaultdict
s 会导致 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