给出基本的书/作者模型:
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey('Author')
publisher = models.ForeignKey('Publisher')
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
让我们说我有一个非常复杂的查询来根据一堆参数选择书籍(我的实际模型比这些复杂得多)。为了简化起见,我对此示例的复杂查询只会选择具有单词""在他们的标题:
q = Book.objects.filter(title__icontains="the")
是否有办法(除了循环或使用反向外键查找)获取链接到此查询中的书籍的所有不同Author
对象?例如。我试过添加:
q = q.values('author').distinct()
但这只会返回author__id values
。我试图这样做,因为我的复杂查询'是时间/资源密集型的,我只想运行一次查询(获取书籍,并分开不同作者的列表)。此外,数据集需要展平(书籍和作者的单独列表),因为它通过django rest框架呈现,我的客户要求数据集是平的。 E.g:
{
"books": [
{"id": 1, "title": "The Book.", "author": 1, "publisher": 1},
{"id": 2, "title": "The Other Book.", "author": 2, "publisher": 1},
{"id": 3, "title": "The Best Book.", "author": 1, "publisher": 1},
],
"authors": [
{"id": 1, "first_name": "Joe", "last_name": "Smith"},
{"id": 2, "first_name": "Gina", "last_name": "Randolph"}
]
}
或者,有一个简单的方法,使用django rest框架来获取带有嵌套外键的复杂查询的结果,并将其展平吗?
答案 0 :(得分:4)
真的,获得作者的最好方法是查询作者而不是书籍。您可以通过双下划线语法来跟踪关系:
q = Author.objects.filter(book__title__icontains="the")
但是既然你说你的查询是密集的,而你更喜欢运行一次,那么另一种方法是使用select_related
来进行JOIN,然后手动处理结果以获得作者:
q = Book.objects.select_related('author').filter(title__icontains="the")
authors = set(book.author for book in q)