我想打印一个字典,按键排序。通过将键放在列表中然后对列表进行排序,可以在视图中轻松地对键进行排序。如何遍历模板中的键,然后从字典中获取值。
{% for company in companies %}
{% for employee, dependents in company_dict.company.items %}
{% endfor %}
{% endfor %}
(刚刚编写的例子......) 无效的部分是“company_dict.company.items”部分。我需要“公司”才能成为公司的价值所在。现在,该公司正在寻找一个名为“公司”的关键,而不是上述循环中“公司”的价值。
我正在做一些处理以将字典字典放在一起。改变数据的布局实际上不是一种选择。我认为正确的方法是编写模板标签,只是想知道我是否错过了内置方式。
答案 0 :(得分:19)
创建一个自定义过滤器,如下所示:
from django import template
from django.utils.datastructures import SortedDict
register = template.Library()
@register.filter(name='sort')
def listsort(value):
if isinstance(value, dict):
new_dict = SortedDict()
key_list = sorted(value.keys())
for key in key_list:
new_dict[key] = value[key]
return new_dict
elif isinstance(value, list):
return sorted(value)
else:
return value
listsort.is_safe = True
然后在你的模板中你应该使用:
来调用它{% for key, value in companies.items|sort %}
{{ key }} {{ value }}
{% endfor %}
您将能够通过Key获取已排序的词典。
答案 1 :(得分:2)
试试这个:http://www.bhphp.com/blog4.php/2009/08/17/django-templates-and-dictionaries
自定义模板过滤器可以解决问题。
from django import template
register = template.Library()
def dict_get(value, arg):
#custom template tag used like so:
#{{dictionary|dict_get:var}}
#where dictionary is duh a dictionary and var is a variable representing
#one of it's keys
return value[arg]
register.filter('dict_get',dict_get)
有关自定义模板过滤器的更多信息:http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags
在您的示例中:
{% for employee, dependents in company_dict|company %}
答案 2 :(得分:1)
这最后一个解决方案对我来说也非常有用。我正在使用Django 1.6.2,它似乎是将一个字典转换为一个列表,其中键作为该列表的第一个元素,内容作为第二个元素。因此,即使我传入一个词典,它也会将其视为一个列表。所以我将上面的内容调整为这样,它对我有用:
@register.filter(name='sort')
def listsort(value):
if isinstance(value, list):
return sorted(value, key=lambda k:k[0])
else:
return value
答案 3 :(得分:0)
对于一些reasone Turikumwe的过滤器对我不起作用(python3.4,Django 1.7),所以我重写它以返回元组列表而不是SertedDict
或OrderedDict
:
@register.filter(name='sort')
def listsort(value):
if isinstance(value, dict):
a = []
key_list = sorted(value.keys())
for key in key_list:
a.append((key, value[key]))
return a
elif isinstance(value, list):
return sorted(value)
else:
return value
listsort.is_safe = True
因此,在模板中,我们不需要获取.items
{% for key, value in companies|sort %}
{{ key }} {{ value }}
{% endfor %}
答案 4 :(得分:0)
Turikumwe的回答让我很接近,但对我的环境不起作用:python3和Django 1.10。
我发现用以下方法调用过滤器:
{% for key, value in companies.items|sort %}
{{ key }} {{ value }}
{% endfor %}
实际上会产生一个ItemsView对象,而不是一个dict。 (我怀疑这是一个python 2 vs 3的问题)。鉴于ItemsView,答案更容易
from django import template
from django.utils.datastructures import ItemsView
register = template.Library()
@register.filter(name='sort')
def listsort(value):
if isinstance(value, ItemsView) or isinstance(value, list):
return sorted(value)
else:
return value
答案 5 :(得分:0)
您可以使用Django的dictsort或dictsortreversed。
{% for user in list_users|dictsort:'created_at' %}
{{user.username}} - {{user.created_at}}
{% endfor %}
或
{% for user in list_users|dictsortreversed:'created_at' %}
{{user.username}} - {{user.created_at}}
{% endfor %}