python 姜戈 | 在模板中对 dict 进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2024660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django | sort dict in template
提问by johannix
I want to print out a dictionary, sorted by the key. Sorting the keys is easy in the view, by just putting the keys in a list and then sorting the list. How can I loop through the keys in the template and then get the value from the dictionary.
我想打印一本字典,按键排序。在视图中对键进行排序很容易,只需将键放入列表中,然后对列表进行排序即可。如何遍历模板中的键,然后从字典中获取值。
{% for company in companies %}
{% for employee, dependents in company_dict.company.items %}
{% endfor %}
{% endfor %}
(Just made up the example...) The part that doesn't work is the "company_dict.company.items" part. I need the "company" to be the value of company. Right now the company prat is looking for a key named "company" not the value of "company" from the loop above.
(只是编造了这个例子......)不起作用的部分是“company_dict.company.items”部分。我需要“公司”成为公司的价值。现在,公司 prat 正在寻找一个名为“company”的键,而不是上面循环中“company”的值。
I'm doing a bit of processing to put the dictionary of dictionaries together. Changing the layout of the data isn't really an option. I figure the right approach is to write up a template tag, just wanted to know if there was a built-in way I missed.
我正在做一些处理以将字典放在一起。改变数据的布局并不是一个真正的选择。我认为正确的方法是写一个模板标签,只是想知道是否有我错过的内置方式。
采纳答案by Brandon Henry
a custom template filter will do the trick.
自定义模板过滤器可以解决问题。
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)
more on custom template filters: http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags
更多关于自定义模板过滤器:http: //docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags
in your example you'd do:
在你的例子中,你会这样做:
{% for employee, dependents in company_dict|company %}
回答by Turikumwe
create a custom filter, which is like this:
创建一个自定义过滤器,如下所示:
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
then in your template you shall call it using:
然后在您的模板中,您将使用以下方法调用它:
{% for key, value in companies.items|sort %}
{{ key }} {{ value }}
{% endfor %}
You will be able to get the sorted dict by Key.
您将能够通过 Key 获得排序的 dict。
回答by user3466943
This last solution was very useful to me too. I'm using Django 1.6.2, and it seems to be converting a dict to a list with the key as the first elemement of that list and the content as the second. So even when I pass in a dict, it treats it as a list. So I tweaked the above to look like this, and it works for me:
最后一个解决方案对我也非常有用。我正在使用 Django 1.6.2,它似乎正在将一个 dict 转换为一个列表,其中键作为该列表的第一个元素,内容作为第二个元素。所以即使我传入一个字典,它也会把它当作一个列表。所以我调整了上面的样子,它对我有用:
@register.filter(name='sort')
def listsort(value):
if isinstance(value, list):
return sorted(value, key=lambda k:k[0])
else:
return value
回答by Ivan Borshchov
for some reasone Turikumwe's filter not worked for me (python3.4, Django 1.7), so I rewrite it to return list of tuples instead of SertedDict
or OrderedDict
:
由于某种原因,Turikumwe 的过滤器对我不起作用(python3.4,Django 1.7),所以我重写它以返回元组列表而不是SertedDict
or 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
So in template we don't need to get .items
所以在模板中我们不需要得到 .items
{% for key, value in companies|sort %}
{{ key }} {{ value }}
{% endfor %}
回答by jim anderson
Turikumwe's answer got me close, but did not work for my environment: python3 and Django 1.10.
Turikumwe 的回答让我很接近,但不适用于我的环境:python3 和 Django 1.10。
I found that invoking the filter with:
我发现调用过滤器:
{% for key, value in companies.items|sort %}
{{ key }} {{ value }}
{% endfor %}
actually results in a ItemsView object, not a dict. (I suspect this is a python 2 vs 3 issue). Given the ItemsView, the answer is even easier
实际上导致 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
回答by Guilherme IA
You can use django's dictsortor dictsortreversed.
您可以使用 django 的dictsort或dictsortreversed。
{% for user in list_users|dictsort:'created_at' %}
{{user.username}} - {{user.created_at}}
{% endfor %}
or
或者
{% for user in list_users|dictsortreversed:'created_at' %}
{{user.username}} - {{user.created_at}}
{% endfor %}