2013-01-09 11 views
6

trzeba uzyskać zestaw zapytań z pierwszą książką (według pola daty) dla każdego autora (powiązanego z kluczem obcym) ... czy istnieje ORM Django sposób to zrobić (bez niestandardowego preferowanego SQL, ale akceptowalny)Zestaw zapytań Django, aby zwrócić pierwszą z każdej pozycji w kluczu obcym na podstawie daty

* Edycja: Proszę zauważyć, że odpowiedź, która działa tylko z nowoczesnym zapleczem open source, takim jak Postgresql, jest akceptowalna... Oparte na ORM rozwiązanie preferowane w stosunku do czystego niestandardowego zapytania SQL.

Models 
class Book(Model): 
    date = Datefield() 
    author = ForeignKey(Author) 

class Author(Model): 
    name = CharField() 


Book.objects.filter(??) 
+0

Miałem prawie to samo pytanie wczoraj http://stackoverflow.com/questions/14213333/get-latest-objects-django. W dziale EDYCJA 2 jest mój obecny hack. –

+0

No cóż, jestem na PostgreSQL, więc nie jestem ograniczony ... Nie jestem pewien, czy mogę znaleźć odpowiedź na podstawie twojego pytania ... dziękuję za wskazówki. – eskhool

Odpowiedz

6

Jeśli używasz PostgreSQL lub inny backend DB ze wsparciem dla DISTINCT ON jest tam ładne rozwiązanie:

Books.objects.order_by('author', '-date').distinct('author') 

W przeciwnym razie nie znam rozwiązania z tylko jednym zapytaniem. Ale można spróbować to:

from django.db.models import Q, Max 
import operator 

books = Book.objects.values('author_id').annotate(max_date=Max('date')) 
filters = reduce(operator.or_, [(Q(author_id=b['author_id']) & 
    Q(date=b['max_date'])) for b in books]) 
queryset = Books.objects.filter(filters) 

Dzięki połączeniu .values ​​() i .annotate() grupa my przez autora i opisywanie ostatnią datę wszystkich książek z tego autora. Ale wynikiem jest dyktando, a nie zestaw pytań. Następnie tworzymy instrukcję SQL, taką jak WHERE author_id=X1 AND date=Y1 OR author_id=X2 AND date=Y2.... Teraz drugie zapytanie jest łatwe.

+0

Dzięki, jestem świadomy 2 odpowiedź na zapytanie ... to prawdopodobnie będzie odpowiedź, którą chciałbym zaakceptować, podaną do tej pory, ponieważ jest w szczegółach i zawiera dokładne pytanie, ale wciąż mam nadzieję, że ORM Django z niestandardowym sql może pozwolić na to w pojedyncze zapytanie – eskhool

+0

Następnie zakładam, że chcesz rozwiązanie dla wszystkich baz danych DB w jednym zapytaniu? Coś takiego: 'Book.objects.raw ('SELECT *, MAX (data) jako max_date FROM myapp_book GROUP BY author_id')'? – Hannes

+0

Zaktualizowałem moje pytanie dotyczące rozwiązania tylko dla PostgreSQL ... nadal wolałbym rozwiązanie oparte na ORM, nawet jeśli nie działa na wszystkich serwerach ... niestandardowe sql tylko utrudniłoby dalsze łańcuchowanie – eskhool