Django queryset根据日期返回外键中每个项目的第一个

esk*_*ool 6 django django-orm

需要为每个作者(与外键相关)获取第一本书(通过日期字段)的查询集...是否有Django ORM方法来执行此操作(没有自定义SQL首选但可接受)

*编辑:请注意,只使用像Postgresql这样的现代开源后端的答案是可以接受的..基于ORM的解决方案比纯自定义sql查询更受欢迎)

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

class Author(Model):
  name = CharField()


Book.objects.filter(??)
Run Code Online (Sandbox Code Playgroud)

小智 7

如果您使用PostgreSQL或其他支持DB的后端,DISTINCT ON那么有一个很好的解决方案:

Books.objects.order_by('author', '-date').distinct('author')
Run Code Online (Sandbox Code Playgroud)

否则我不知道只有一个查询的解决方案.但你可以尝试这个:

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)
Run Code Online (Sandbox Code Playgroud)

通过.values()和.annotate()的组合,我们将作者分组并注释该作者所有书籍的最新日期.但结果是dict而不是查询集.然后我们构建一个类似的SQL语句WHERE author_id=X1 AND date=Y1 OR author_id=X2 AND date=Y2....现在第二个查询很简单.