Можно ли отсортировать набор связанных элементов в шаблоне DJango?
То есть: этот код (без тегов HTML для ясности):
{% for event in eventsCollection %}
{{ event.location }}
{% for attendee in event.attendee_set.all %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
отображает почти точно хочу хочу. Единственное, что я хочу изменить, это список участников, которые будут отсортированы по фамилии. Я пробовал сказать что-то вроде этого:
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_set.order_by__last_name %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
Увы, приведенный выше синтаксис не работает (он создает пустой список), как и другие варианты, о которых я думал (сообщалось о множестве синтаксических ошибок, но без радости).
Я мог бы, конечно, создать какой-то массив отсортированных списков посетителей, на мой взгляд, но это уродливое и хрупкое (и я уже упоминал уродливое) решение.
Излишне говорить, но я все равно скажу, что я просмотрел онлайн-документацию и искал переполнение стека и архивы django-user, но не нашел ничего полезного (ах, если бы только набор запросов был словарём, dictsort сделал бы работа, но это не так и не работает)
==============================================
Отредактировано, чтобы добавить дополнительные мысли после принятия ответа Таумаса.
Таумас обратился к проблеме точно так, как я ее представил, хотя решение оказалось не таким, как я ожидал. В результате я узнал полезную технику, которую можно использовать и в других ситуациях.
Ответ Тома предлагал подход, который я уже упоминал в моем OP и предварительно отклонил как "уродливый".
«Уродливое» было интуитивной реакцией, и я хотел прояснить, что с этим не так. Поступая так, я понял, что это был уродливый подход, потому что я был зациклен на идее передать набор запросов в шаблон для отображения. Если я ослаблю это требование, появится некрасивый подход, который должен сработать.
Я не пробовал этого, но предположу , что вместо прохождения QuerySet, вид код итерации через набор запросов производящего список событий, затем украшенный каждое событие с набором запросов для соответствующих участников , которые БЫЛИ отсортированные (или фильтруется, или что-то еще) желаемым образом. Примерно так:
eventCollection = []
events = Event.object.[filtered and sorted to taste]
for event in events:
event.attendee_list = event.attendee_set.[filtered and sorted to taste]
eventCollection.append(event)
Теперь шаблон становится:
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_list %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
Обратной стороной является то, что представление должно «актуализировать» все события сразу, что могло бы стать проблемой, если бы было большое количество событий. Конечно, можно добавить нумерацию страниц, но это значительно усложняет просмотр.
Положительным моментом является то, что код «подготовить данные для отображения» находится в представлении, которому он принадлежит, позволяя шаблону сосредоточиться на форматировании данных, предоставляемых представлением для отображения. Это правильно и правильно.
Итак, мой план состоит в том, чтобы использовать технику Таумаса для больших таблиц и описанную выше технику для маленьких столов, оставляя определение больших и малых для читателя (усмехается).
источник
@property
здесь перебор, поскольку здесь нет геттеров или сеттеров: stackoverflow.com/questions/1554546/…Вы можете использовать шаблон фильтра dictsort https://docs.djangoproject.com/en/dev/ref/templates/builtins/#std:templatefilter-dictsort
Это должно работать:
{% for event in eventsCollection %} {{ event.location }} {% for attendee in event.attendee_set.all|dictsort:"last_name" %} {{ attendee.first_name }} {{ attendee.last_name }} {% endfor %} {% endfor %}
источник
dictsortreversed
: docs.djangoproject.com/en/dev/ref/templates/builtins/…dictsort
правильно работаю над кодом почти так же, как ваш. Что интересно, похоже, он отлично работает с наборами запросов.{% for attendee in event.attendee_set.all|dictsort:"last_name" %}
сортирует участников, но{% for attendee in event.attendee_set.all | dictsort:"last_name" %}
пытается отсортировать вывод цикла for и прерываетfor
.Одно из решений - создать собственный шаблонный тег:
@register.filter def order_by(queryset, args): args = [x.strip() for x in args.split(',')] return queryset.order_by(*args)
использовать так:
{% for image in instance.folder.files|order_by:"original_filename" %} ... {% endfor %}
источник
перегруппировка должна иметь возможность делать то, что вы хотите, но есть ли причина, по которой вы не можете упорядочить их так, как хотите, обратно в представление?
источник