Django queryset to return first of each item in foreign key based on date

不问归期 提交于 2019-12-30 09:22:08

问题


need to get a queryset with the first book (by a date field) for each author (related to by foreign key) ...is there a Django ORM way to do this (without custom SQL preferred but acceptable)

*Edit: Please note that an answer that works using only a modern open source backend like Postgresql is acceptable ..still ORM based solution preferred over pure custom sql query)

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

class Author(Model):
  name = CharField()


Book.objects.filter(??)

回答1:


If you use PostgreSQL or another DB backend with support for DISTINCT ON there is a nice solution:

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

Otherwise I don't know a solution with only one query. But you can try this:

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)

With the combination of .values() and .annotate() we group by the author and annotate the latest date of all books from that author. But the result is a dict and not a queryset. Then we build a SQL statement like WHERE author_id=X1 AND date=Y1 OR author_id=X2 AND date=Y2.... Now the second query is easy.



来源:https://stackoverflow.com/questions/14234971/django-queryset-to-return-first-of-each-item-in-foreign-key-based-on-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!