Django使用值方法与m2m关系/使用django过滤m2m表

时间:2012-02-08 05:14:59

标签: django django-models django-queryset django-orm

class Book(models.Model):
    name = models.CharField(max_length=127, blank=False)

class Author(models.Model):
    name = models.CharField(max_length=127, blank=False)
    books = models.ManyToMany(Books)

我正在尝试过滤作者,以便我可以返回作者的结果集:

[{id: 1, name: 'Grisham', books : [{name: 'The Client'},{name: 'The Street Lawyer}], ..]

在我与作者建立m2m关系之前,我能够查询任意数量的作者记录,并使用只有一个db查询的values方法获取我需要的所有值。

但看起来像是

Author.objects.all().values('name', 'books')

会返回类似的内容:

[{id: 1, name: 'Grisham', books :{name: 'The Client'}},{id: 1, name: 'Grisham', books :{name: 'The Street Lawyer'}}]

使用values方法查看文档看起来不太可能 https://docs.djangoproject.com/en/dev/ref/models/querysets/

  

警告因为ManyToManyField属性和反向关系都可以   有多个相关的行,包括这些可以有一个乘数   对结果集大小的影响。这将是特别的   如果在values()查询中包含多个这样的字段,则发音   在这种情况下,将返回所有可能的组合。

我想尝试获得n大小的结果集,并且使用最少的数据库命中authorObject.books.all()将导致至少n db命中。

有没有办法在django中这样做?

我认为使用最少量的数据库命中执行此操作的一种方法是:

authors = Authors.objects.all().values('id')
q = Q()
for id in authors:
   q = q | Q(author__id = id)

#m2m author book table.. from my understanding it is 
#not accessible in the django QuerySet
author_author_books.filter(q)  #grab all of the book ids and author ids with one query

是否有内置的方法来查询m2m author_author_books表或者我是否要编写sql?有没有办法利用Q()在原始sql中进行OR逻辑?

提前致谢。

1 个答案:

答案 0 :(得分:1)

我认为你想要prefetch_related。像这样:

authors = Author.objects.prefetch_related('books').all()

有关此here的详情。

如果您想查询author_author_books表,我认为您需要指定一个“通过”表:

class BookAuthor(models.Model):
  book = models.ForeignKey(Book)
  author = models.ForeignKey(Author)

class Author(models.Model):
  name = models.CharField(max_length=127, blank=False)
  books = models.ManyToMany(Books, through=BookAuthor)

然后您可以像任何其他模型一样查询BookAuthor。