使用 django 查询集访问不同的外键关系
Posted
技术标签:
【中文标题】使用 django 查询集访问不同的外键关系【英文标题】:Accessing distinct foreign key relationships with django queryset 【发布时间】:2018-11-26 04:33:04 【问题描述】:给定基本的书籍/作者模型:
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)
假设我有一个非常复杂的查询来根据一堆参数选择书籍(我的实际模型比这些复杂得多)。为简单起见,我对这个示例的复杂查询将只选择标题中包含“the”一词的书籍:
q = Book.objects.filter(title__icontains="the")
有没有办法(除了循环,或使用反向外键查找)来获取链接到此查询中书籍的所有不同的Author
对象?例如。我已经尝试添加:
q = q.values('author').distinct()
但这只是返回author__id values
。我正在尝试以这种方式进行,因为我的“复杂查询”非常耗费时间/资源,我只想运行一次该查询(以获取书籍,并分离不同作者的列表)。此外,数据集需要展平(书籍和作者的单独列表),因为它是通过 django rest 框架呈现的,我的客户要求数据集是展平的。例如:
"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 框架是否有一种简单的方法来获取具有嵌套外键的复杂查询的结果,并将其展平?
【问题讨论】:
【参考方案1】:确实,获取作者的最佳方式是查询作者而不是书籍。您可以通过双下划线语法遵循关系:
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)
【讨论】:
以上是关于使用 django 查询集访问不同的外键关系的主要内容,如果未能解决你的问题,请参考以下文章