Подтвердить что ты не робот

Сортировка связанных элементов в шаблоне Django

Можно ли отсортировать набор связанных элементов в шаблоне 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 %}

Увы, приведенный выше синтаксис не работает (он создает пустой список), и ни одна другая вариация, о которой я думал (много сообщений об ошибках синтаксиса, но без радости).

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

Излишне говорить, но я все равно скажу, что я просматривал он-лайн документы и искал Qaru и архивы django-user, не найдя ничего полезного (ах, если только набор запросов был словарным указателем словаря выполнял бы эту работу, но это не так, и это не так)

==============================================

Отредактировано, чтобы добавить дополнительные мысли после принятия ответа Tawmas.


Таумас обратился к проблеме именно так, как я ее представил, хотя решение было не тем, что я ожидал. В результате я узнал полезный метод, который можно использовать и в других ситуациях.

Tom ответ предложил предложенный мной подход в моем OP и условно отвергнут как "уродливый".

"Уродливая" была реакцией кишки, и я хотел уточнить, что с ней не так. При этом я понял, что причина, по которой это был уродливый подход, состояла в том, что меня повесили на мысль о передаче запроса, заданного шаблону, который нужно визуализировать. Если я ослаблю это требование, есть не уродливый подход, который должен работать.

Я еще не пробовал этого, но предположим, что вместо того, чтобы передавать запрос, код представления повторяется через набор запросов, создавая список событий, а затем оформляет каждое событие с набором запросов для соответствующих участников, которые были отсортированы ( или фильтровать, или что угодно) желаемым образом. Что-то вроде этого:

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

Недостатком является то, что представление должно "актуализировать" все события сразу, что может быть проблемой, если было большое количество событий. Конечно, можно добавить разбивку на страницы, но это значительно усложняет представление.

Поверхность - это "подготовить данные, которые будут отображаться", код находится в представлении, где он принадлежит, позволяя шаблону сосредоточиться на форматировании данных, предоставленных представлением для отображения. Это правильно и правильно.

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

4b9b3361

Ответ 1

Вам нужно указать порядок в модели участника, например. Например (если ваш модельный класс называется Attendee):

class Attendee(models.Model):
    class Meta:
        ordering = ['last_name']

Подробнее см. руководство.

ИЗМЕНИТЬ. Другим решением является добавление свойства к вашей модели событий, доступ к которой вы можете получить из своего шаблона:

class Event(models.Model):
# ...
@property
def sorted_attendee_set(self):
    return self.attendee_set.order_by('last_name')

Вы можете определить больше из них, сколько вам нужно...

Ответ 3

Одним из решений является создание собственного шаблона:

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

Ответ 4

regroup должен быть в состоянии делать то, что вы хотите, но есть причина, по которой вы не можете заказать их так, как хотите в представлении?