python - 使用 Django 查询集访问不同的外键关系

标签 python django django-rest-framework foreign-keys django-queryset

给定基本的书籍/作者模型:

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 值。我正在尝试以这种方式进行处理,因为我的“复杂查询”非常耗费时间/资源,而且我只想运行该查询一次(以获取书籍,并将不同作者的列表分开)。此外,数据集需要展平(一个单独的书籍和作者列表),因为它是通过 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 框架是否有一种简单的方法来获取带有嵌套外键的复杂查询的结果,并将其展平?

最佳答案

确实,获取作者的最佳方式是查询作者而不是书籍。您可以通过双下划线语法遵循关系:

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)

关于python - 使用 Django 查询集访问不同的外键关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50890662/

相关文章:

python - Google App Engine - 是否有必要在处理程序中调用 self.response?

python - “SSL: CERTIFICATE_VERIFY_FAILED” 发布 MQTT、AWS IoT 时出错

python - django paypal paypalrestsdk - 如何执行付款?没有返回 HttpResponse 对象

python - 没有名为 rest_authusers 的模块错误

python - 模型查询,选择过滤

python - 追加列表、数组、矩阵

python - 在 Pandas 中创建多个移位(滞后)列

python - 如何在django中存储用户数组?

python - RabbitMQ 或 Redis 使用 Django 2.0 扩展 Celery 队列

Django rest framework - 序列化器字段的过滤