2010-02-01 20 views
8

Tengo un modelo para nuestros clientes y un modelo para sus compras/pedidos. En nuestro administrador de backend/web, queremos poder ordenar la lista de clientes por su orden más reciente.Django order_by a related _set

Aquí es básicamente lo que nuestros modelos se parecen a

class Customer(models.Model): 
    username = models.CharField(max_length=32) 
    first_name = models.CharField(max_length=322) 
    def __unicode__(self): 
     return "%s" % self.username 
    def get_last_order_date(self): 
     self.order_set.latest('purchase_date') 

class Order(models.Model): 
    customer = models.ForeignKey(Customer) 
    purchase_date = models.DateTimeField() 

puedo mostrar la orden más reciente de cada cliente a través de mi función get_last_order_date, sin embargo no puedo ordenar por esa función (o al menos yo don' t saber cómo). He intentado todo lo que puedo pensar:

.order_by('order__purchase_date') 
.order_by('order__set').latest('purchase_date') 

y mucho más sin suerte.

Cualquier sugerencia o pista sería muy apreciada.

Gracias.

Respuesta

12

No se puede usar el orden con una función, ya que se hace en el nivel de la base de datos. Puedes ordenar manualmente el queryset usando. sort(key=get_last_order_date), pero esto no será muy eficiente.

Una mejor manera sería utilizar la función de agregación de Django, para obtener la fecha de compra máximo para un cliente y ordenación en que:

from django.db.models import Max 
Customer.objects.annotate(latest_order=Max('order__purchase_date')).order_by('latest_order') 
+2

Gracias tan mucho! He estado leyendo y volviendo a leer los documentos y buscando en la red por un tiempo. Había creado una "solución" usando sorted() pero realmente no me gustaba la ineficiencia. Gracias de nuevo. – mhost

+0

¡Finalmente encontré la manera de hacerlo! ¡Muchas gracias, Daniel! – marcelosalloum

0

Definitivamente no se puede pedir por su método personalizado (debido a su base de datos no lo sabe).

Ahora, parece difícil de hacer lo que quiere en el nivel del modelo, así que tal vez moverlo a la vista y para el uso de Python, así:

sorted(Customer.objects.all(), key=get_last_order_date) 
Cuestiones relacionadas