Django ManyToManyField访问相关数据的最佳方式

时间:2015-04-02 13:26:28

标签: python django orm relational-database

我有两个以下具有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()

但这看起来非常昂贵。什么是获得相关作者的最佳方式。

2 个答案:

答案 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)