Ist es möglich, eine Reihe verwandter Elemente in einer DJango-Vorlage zu sortieren?
Das heißt: dieser Code (wobei HTML-Tags aus Gründen der Übersichtlichkeit weggelassen wurden):
{% for event in eventsCollection %}
{{ event.location }}
{% for attendee in event.attendee_set.all %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
Displays wollen fast genau ich will. Das einzige, was ich ändern möchte, ist die Liste der Teilnehmer, die nach Nachnamen sortiert werden sollen. Ich habe versucht, so etwas zu sagen:
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_set.order_by__last_name %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
Leider funktioniert die obige Syntax nicht (sie erzeugt eine leere Liste) und auch keine andere Variation, an die ich gedacht habe (viele Syntaxfehler wurden gemeldet, aber keine Freude).
Ich könnte meiner Ansicht nach natürlich eine Reihe sortierter Teilnehmerlisten erstellen, aber das ist eine hässliche und fragile (und habe ich hässliche erwähnt) Lösung.
Unnötig zu sagen, aber ich werde es trotzdem sagen, ich habe die Online-Dokumente durchgesehen und Stack Overflow und die Archive von Django-Benutzern durchsucht, ohne etwas Hilfreiches zu finden (ah, wenn nur ein Abfragesatz ein Wörterbuch wäre, würde Dictsort das tun Job, aber es ist nicht und es nicht)
==============================================
Bearbeitet, um zusätzliche Gedanken hinzuzufügen, nachdem Tawmas 'Antwort akzeptiert wurde.
Tawmas ging das Problem genau so an, wie ich es vorgestellt hatte - obwohl die Lösung nicht meinen Erwartungen entsprach. Als Ergebnis habe ich eine nützliche Technik gelernt, die auch in anderen Situationen angewendet werden kann.
Toms Antwort schlug einen Ansatz vor, den ich bereits in meinem OP erwähnt und vorläufig als "hässlich" abgelehnt hatte.
Das "Hässliche" war eine Bauchreaktion, und ich wollte klarstellen, was daran falsch war. Dabei wurde mir klar, dass der Grund dafür ein hässlicher Ansatz war, weil ich auf die Idee gekommen war, einen Abfragesatz an die zu rendernde Vorlage zu übergeben. Wenn ich diese Anforderung lockere, gibt es einen hässlichen Ansatz, der funktionieren sollte.
Ich habe das noch nicht ausprobiert, aber annehmen , dass anstatt die queryset vorbei, die View - Code durch den Abfragesatz iteriert, eine Liste der Ereignisse produzieren dann jedes Ereignis mit einer Abfrage für die entsprechenden Teilnehmer eingerichtet , die WAR sortiert (oder gefiltert, oder was auch immer) auf die gewünschte Weise. So etwas in der Art:
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)
Jetzt wird die Vorlage:
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_list %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
Der Nachteil ist, dass die Ansicht alle Ereignisse auf einmal "aktualisieren" muss, was ein Problem sein könnte, wenn es eine große Anzahl von Ereignissen gibt. Natürlich könnte man Paginierung hinzufügen, aber das erschwert die Ansicht erheblich.
Der Vorteil ist, dass sich der Code "Vorbereiten der anzuzeigenden Daten" in der Ansicht befindet, in die er gehört, sodass sich die Vorlage auf die Formatierung der von der Ansicht zur Anzeige bereitgestellten Daten konzentrieren kann. Das ist richtig und richtig.
Mein Plan ist es also, die Tawmas-Technik für große Tische und die obige Technik für kleine Tische zu verwenden, wobei die Definition von groß und klein dem Leser überlassen bleibt (grins).
quelle
@property
ist es hier übertrieben, da keine Getter oder Setter beteiligt sind: stackoverflow.com/questions/1554546/…Sie können den Vorlagenfilter dictsort https://docs.djangoproject.com/de/dev/ref/templates/builtins/#std:templatefilter-dictsort verwenden
Das sollte funktionieren:
quelle
dictsortreversed
: docs.djangoproject.com/de/dev/ref/templates/builtins/…dictsort
richtig mit Code gearbeitet, fast genau wie bei Ihnen. Interessanterweise scheint es bei Abfragesätzen gut zu funktionieren.{% for attendee in event.attendee_set.all|dictsort:"last_name" %}
Sortiert die Teilnehmer,{% for attendee in event.attendee_set.all | dictsort:"last_name" %}
versucht jedoch, die Ausgabe der for-Schleife zu sortieren, und unterbricht diefor
.Eine Lösung besteht darin, ein benutzerdefiniertes Templatag zu erstellen:
Verwendung wie folgt:
quelle
regroup sollte in der Lage sein zu tun, was Sie wollen, aber gibt es einen Grund, warum Sie sie nicht so bestellen können, wie Sie es möchten?
quelle