2010-02-01 11 views
8

Mam model dla naszych klientów i model ich zakupów/zamówień. W naszym zapleczu/administratorze sieci chcemy mieć możliwość sortowania listy klientów według ich ostatniego zamówienia.Django order_by a related _set

Oto zasadzie co nasi modele wyglądać

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

mogę wyświetlić ostatnie zamówienie każdego klienta przy moim funkcję get_last_order_date, jednak nie mogę sortować według tej funkcji (lub przynajmniej I don” t know how). Próbowałem wszystkiego, co mogę wymyślić:

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

i wiele więcej bez powodzenia.

Wszelkie wskazówki i wskazówki będą bardzo mile widziane.

Dzięki.

Odpowiedz

12

Nie można używać kolejności według funkcji, ponieważ jest ona wykonywana na poziomie bazy danych. Możesz ręcznie sortować zestaw zapytań za pomocą. sort(key=get_last_order_date), ale nie będzie to bardzo wydajne.

Lepszym sposobem byłoby użyć funkcji agregacji Django, aby uzyskać maksymalną datę zakupu dla klienta i porządek na ten temat:

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

Dziękuję taaak dużo! Czytałem i ponownie czytałem dokumenty i przeszukiwałem sieć przez jakiś czas. Stworzyłem "rozwiązanie" używając sorted(), ale naprawdę nie podobało mi się nieefektywność. Dzięki jeszcze raz. – mhost

+0

Wreszcie znalazłem sposób na zrobienie tego! Dziękuję bardzo Daniel! – marcelosalloum

0

pewno nie można zamówić przez metodę niestandardowego (ponieważ baza danych o tym nie wie).

Teraz wydaje się trudne do zrobienia, co chcesz na poziomie modelu, więc może go przenieść do widoku i porządku przy użyciu Pythona, tak:

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