Django |在模板中排序字典

时间:2010-01-08 00:13:51

标签: python django

我想打印一个字典,按键排序。通过将键放在列表中然后对列表进行排序,可以在视图中轻松地对键进行排序。如何遍历模板中的键,然后从字典中获取值。

{% for company in companies %}
    {% for employee, dependents in company_dict.company.items %}
    {% endfor %}
{% endfor %}

(刚刚编写的例子......) 无效的部分是“company_dict.company.items”部分。我需要“公司”才能成为公司的价值所在。现在,该公司正在寻找一个名为“公司”的关键,而不是上述循环中“公司”的价值。

我正在做一些处理以将字典字典放在一起。改变数据的布局实际上不是一种选择。我认为正确的方法是编写模板标签,只是想知道我是否错过了内置方式。

6 个答案:

答案 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),所以我重写它以返回元组列表而不是SertedDictOrderedDict

@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的dictsortdictsortreversed

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