Est-il possible de trier un ensemble d'éléments connexes dans un modèle DJango ?
C'est-à-dire : ce code (avec les balises HTML omises pour plus de clarté) :
{% for event in eventsCollection %}
{{ event.location }}
{% for attendee in event.attendee_set.all %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
affichages presque exactement ce que je veux. La seule chose que je souhaite modifier est que la liste des participants soit triée par nom de famille. J'ai essayé de dire quelque chose comme ceci :
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_set.order_by__last_name %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
Hélas, la syntaxe ci-dessus ne fonctionne pas (elle produit une liste vide), pas plus que les autres variantes auxquelles j'ai pensé (de nombreuses erreurs de syntaxe sont signalées, mais rien ne se passe).
Je pourrais, bien sûr, produire une sorte de tableau de listes de participants triées dans ma vue, mais c'est une solution laide et fragile (et ai-je mentionné la laideur).
Inutile de dire, mais je vais le dire quand même, que j'ai parcouru la documentation en ligne et cherché sur Stack Overflow et dans les archives de django-user sans rien trouver d'utile (ah, si seulement un ensemble de requêtes était un dictionnaire dictsort ferait l'affaire, mais ce n'est pas le cas et ça ne marche pas).
\==============================================
Modification de l'article pour ajouter des réflexions supplémentaires après avoir accepté la réponse de Tawmas.
Tawmas a abordé le problème exactement comme je l'avais présenté, même si la solution n'était pas celle à laquelle je m'attendais. J'ai ainsi appris une technique utile qui peut être utilisée dans d'autres situations.
La réponse de Tom proposait une approche que j'avais déjà mentionnée dans mon OP et que j'avais provisoirement rejetée parce qu'elle était "laide".
Le "moche" était une réaction instinctive, et je voulais clarifier ce qui n'allait pas. Ce faisant, je me suis rendu compte que la raison pour laquelle cette approche était laide était que j'étais accroché à l'idée de passer un ensemble de requêtes au modèle pour qu'il soit rendu. Si je relâche cette exigence, il existe une approche non laide qui devrait fonctionner.
Je n'ai pas encore essayé, mais supposons qu'au lieu de transmettre l'ensemble de requêtes, le code de la vue itère à travers l'ensemble de requêtes pour produire une liste d'événements, puis décore chaque événement avec un ensemble de requêtes pour les participants correspondants qui WAS trié (ou filtré, ou autre) de la manière souhaitée. Quelque chose comme ça :
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)
Le modèle devient alors :
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_list %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
L'inconvénient est que la vue doit "actualiser" tous les événements en même temps, ce qui peut poser un problème s'il y a un grand nombre d'événements. Bien sûr, on peut ajouter la pagination, mais cela complique considérablement la vue.
L'avantage est que le code de "préparation des données à afficher" se trouve dans la vue, à sa place, ce qui permet au modèle de se concentrer sur le formatage des données fournies par la vue pour l'affichage. C'est une bonne chose.
J'ai donc l'intention d'utiliser la technique de Tawmas pour les grandes tables et la technique ci-dessus pour les petites. pour les petits tableaux, la définition de grand et petit étant laissée au lecteur (grincheux).