Джанго | сортировать dict в шаблоне - PullRequest
8 голосов
/ 08 января 2010

Я хочу распечатать словарь, отсортированный по ключу. Сортировать ключи легко в представлении, просто поместив ключи в список, а затем отсортировав список. Как я могу перебрать ключи в шаблоне и затем получить значение из словаря.

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

(только что составил пример ...) Часть, которая не работает, является частью "company_dict.company.items". Мне нужно, чтобы «компания» была ценностью компании. Прямо сейчас компания prat ищет ключ с именем "company", а не значение "company" из цикла выше.

Я делаю небольшую обработку, чтобы собрать словарь словарей. Изменение формата данных на самом деле не вариант. Я полагаю, что правильный подход - написать тег шаблона, просто хотел узнать, был ли встроенный способ, который я пропустил.

Ответы [ 5 ]

19 голосов
/ 08 ноября 2011

создайте пользовательский фильтр, подобный этому:

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

Вы сможете получить отсортированный диктант по ключу.

3 голосов
/ 08 января 2010

попробуйте это: 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 %}
1 голос
/ 25 сентября 2014

Это последнее решение было очень полезно и для меня.Я использую 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
0 голосов
/ 20 ноября 2016

Ответ Турикумве сблизил меня, но не сработал для моей среды: python3 и Django 1.10.

Я обнаружил, что вызов фильтра с:

{% for key, value in companies.items|sort %}
      {{ key }} {{ value }}
{% endfor %}

фактически приводит к объекту ItemsView, а не к диктату. (Я подозреваю, что это проблема Python 2 против 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
0 голосов
/ 11 мая 2016

по некоторым причинам фильтр Турикумве не работал для меня (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 %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...