variable template plantillas examples python django django-templates sql-order-by

python - template - load tags django



Ordenando elementos relacionados en una plantilla de Django (3)

¿Es posible ordenar un conjunto de elementos relacionados en una plantilla de DJango?

Es decir: este código (con etiquetas HTML omitidas para mayor claridad):

{% for event in eventsCollection %} {{ event.location }} {% for attendee in event.attendee_set.all %} {{ attendee.first_name }} {{ attendee.last_name }} {% endfor %} {% endfor %}

muestra casi exactamente lo que quiero. Lo único que quiero cambiar es la lista de asistentes que se ordenarán por apellido. Intenté decir algo como esto:

{% for event in events %} {{ event.location }} {% for attendee in event.attendee_set.order_by__last_name %} {{ attendee.first_name }} {{ attendee.last_name }} {% endfor %} {% endfor %}

Por desgracia, la sintaxis anterior no funciona (produce una lista vacía) y tampoco ninguna otra variación en la que haya pensado (muchos informes de errores de sintaxis, pero no de alegría).

Podría, por supuesto, producir algún tipo de arreglo de listas ordenadas de asistentes, desde mi punto de vista, pero esa es una solución fea y frágil (y he mencionado feo).

No hace falta decirlo, pero lo diré de todos modos, he leído detenidamente los documentos en línea y busqué Stack Overflow y los archivos de django-usuario sin encontrar nada útil (ah, si solo un conjunto de consultas fuera un dictsort de diccionario haría el trabajo, pero no es y no lo es)

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

Editado para agregar pensamientos adicionales después de aceptar la respuesta de Tawmas.

Tawmas abordó el problema exactamente como lo presenté, aunque la solución no era la que esperaba. Como resultado, aprendí una técnica útil que también puede usarse en otras situaciones.

La respuesta de Tom propuso un enfoque que ya había mencionado en mi OP y que tentativamente rechacé como "feo".

Lo "feo" fue una reacción visceral, y quería aclarar qué le pasaba. Al hacerlo, me di cuenta de que la razón por la que era un enfoque feo era porque me obsesionaba con la idea de pasar un conjunto de consultas a la plantilla que se iba a representar. Si relajo ese requisito, hay un enfoque desagradable que debería funcionar.

No he intentado esto todavía, pero supongo que en lugar de pasar el conjunto de consulta, el código de vista iteraba a través del conjunto de consultas produciendo una lista de Eventos, luego decoraba cada Evento con un conjunto de consultas para los asistentes correspondientes que WAS clasificó (o filtró, o lo que sea) de la manera deseada. Algo así:

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)

Ahora la plantilla se convierte en:

{% for event in events %} {{ event.location }} {% for attendee in event.attendee_list %} {{ attendee.first_name }} {{ attendee.last_name }} {% endfor %} {% endfor %}

La desventaja es que la vista tiene que "actualizar" todos los eventos a la vez, lo que podría ser un problema si hubiera un gran número de eventos. Por supuesto, uno podría agregar paginación, pero eso complica considerablemente la vista.

La ventaja es que el código "prepare the data to be displayed" se encuentra en la vista donde pertenece, dejando que la plantilla se concentre en formatear los datos provistos por la vista para su visualización. Esto es correcto y correcto.

Así que mi plan es usar la técnica de Tawmas para tablas grandes y la técnica anterior para tablas pequeñas, con la definición de grande y pequeña para el lector (sonrisa).


Debe especificar el orden en el modelo de asistentes, así. Por ejemplo (suponiendo que su clase de modelo se llame asistente):

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

Vea el manual para mayor referencia.

EDITAR Otra solución es agregar una propiedad a su modelo de evento, a la que puede acceder desde su plantilla:

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

Podrías definir más de estos cuando los necesites ...


reagrupar debe ser capaz de hacer lo que quiera, pero ¿hay alguna razón por la que no pueda ordenarlos de la manera que desea volver a la vista?