2010-02-01 4 views
8

J'ai un modèle pour nos clients et un modèle pour leurs achats/commandes. Dans notre backend/administrateur web, nous voulons être en mesure de trier la liste des clients par leur commande la plus récente.Django order_by a _set

Voici essentiellement ce que nos modèles ressemblent à

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() 

Je peux afficher l'ordre le plus récent de chaque client en utilisant ma fonction get_last_order_date, mais je ne peux pas trier par cette fonction (ou du moins je n » je sais comment). J'ai essayé tout ce que je peux penser:

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

et beaucoup plus sans chance.

Tous les indices ou indices seraient très appréciés.

Merci.

Répondre

12

Vous ne pouvez pas utiliser order by avec une fonction, comme c'est le cas au niveau de la base de données. Vous pouvez trier manuellement le jeu de requête à l'aide de. sort(key=get_last_order_date), mais ce ne sera pas très efficace.

Une meilleure façon serait d'utiliser la fonction d'agrégation de Django, pour obtenir la date d'achat maximum pour un client et trier sur ce point:

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

Merci sooo beaucoup! J'ai lu et relu les documents et cherché sur le net pendant un moment. J'avais créé une "solution" en utilisant sorted() mais je n'ai vraiment pas aimé l'inefficacité. Merci encore. – mhost

+0

Enfin trouvé un moyen de le faire! Merci beaucoup Daniel! – marcelosalloum

0

Vous pouvez certainement pas commander par votre méthode personnalisée (parce que votre base de données ne sait pas à ce sujet).

Maintenant, il semble difficile de faire ce que vous voulez au niveau du modèle, donc peut-être passer à la vue et de l'ordre en utilisant python, comme ceci:

sorted(Customer.objects.all(), key=get_last_order_date) 
Questions connexes