我有两个以下具有ManyToManyField关系的django模型
预订模型
class Book(models.Model):
title = models.TextField()
authors = models.ManyToManyField('authors.Author')
作者模型
class Author(models.Model):
name = models.CharField(max_length=200)
让我们说我通过运行查询来获取所有书籍
books = Book.objects.filter(name="some value").prefect_related('authors')
使所有作者与上述成果相关的优化方法是什么。
我现在正在尝试的是
authors = []
for book in books:
for author in book.authors.all():
authors.append(author.id)
authors = Author.objects.filter(id__in=authors).distinct()
但这看起来非常昂贵。什么是获得相关作者的最佳方式。
答案 0 :(得分:2)
即使使用昂贵的方法,也无需在最后再次查询作者:在每个内部循环中,author
已经是一个Author实例,因此您可以将其附加到列表而不是ID。
但是你是对的,有一个更便宜的方法,那就是直接在查询中使用关系。与往常一样,如果您想要作者,您应该从作者开始并遍历书籍:
authors = Author.objects.filter(book__in=Book.authors.all())
将转换为带有子查询的单个查询。
这可能更便宜:
authors = Author.objects.exclude(book=None)
因为这是一个简单的JOIN,在这种情况下它应该给你相同的结果。
答案 1 :(得分:1)
如果您只需要作者,则只需查询book__name
:
authors = Author.objects.filter(book__name="some value")
您可以使用.prefetch_related('book')
预取图书。如果您确实需要书籍和作者的平面列表,则可以跳过prefetch_related
并执行此操作:
books = Book.objects.filter(name="some value")
authors = Author.objects.filter(book__in=books)