2013-01-09 56 views
6

需要为每个作者(与外键相关)的第一本书(通过日期字段)获得一个查询集...是否有Django ORM方法来做到这一点(没有自定义的SQL首选,但可以接受)Django queryset返回基于日期的外键每个项目的第一个

*编辑:请注意,一个只适用于现代开放源码后端像Postgresql的答案是可接受的..静态ORM为基础的解决方案首选纯自定义SQL查询)

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

class Author(Model): 
    name = CharField() 


Book.objects.filter(??) 
+0

我有几乎相同的问题昨天http://stackoverflow.com/questions/14213333/get-latest-objects-django。在编辑2部分是我目前的黑客。 –

+0

嗯,我在PostgreSQL上,所以我不受限于独特的...我不知道如果我可以根据您的问题找到我的答案...感谢指针 – eskhool

回答

6

如果你使用PostgreSQL或其他数据库后端,可支持DISTINCT ON有一个很好的解决方案:

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

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

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) 

有().values的组合和.annotate(),我们组由作者和注释的从作者的所有书籍的最后日期。但结果是字典而不是查询集。 然后我们建立一个SQL语句,如WHERE author_id=X1 AND date=Y1 OR author_id=X2 AND date=Y2...。现在第二个查询很容易。

+0

谢谢,我知道2查询回复...这可能是我想要接受的答案,因为它已经详细地讨论了具体的问题,但我仍然希望Django ORM与自定义sql可能允许这发生在单个查询 – eskhool

+0

然后我假设你想在单个查询中为所有数据库后端提供解决方案?像这样:'Book.objects.raw('SELECT *,MAX(date)as max_date FROM myapp_book GROUP BY author_id')'? – Hannes

+0

更新了我的问题,仅适用于postgresql解决方案...即使它不适用于所有后端,仍然更愿意使用基于ORM的解决方案...自定义sql只会导致进一步链接困难 – eskhool

相关问题