一尘不染

Django:对列表中的所有项目进行匹配的ManyToMany过滤器

django

我有这样的Book模型:

class Book(models.Model):
    authors = models.ManyToManyField(Author, ...)
    ...

简而言之:

我想检索作者严格等于给定作者集的书籍。我不确定是否有单个查询可以执行此操作,但是任何建议都会有所帮助。

总而言之:

这是我尝试过的((无法运行得到AttributeError)

# A sample set of authors
target_authors = set((author_1, author_2))

# To reduce the search space, 
# first retrieve those books with just 2 authors.
candidate_books = Book.objects.annotate(c=Count('authors')).filter(c=len(target_authors))

final_books = QuerySet()
for author in target_authors:
    temp_books = candidate_books.filter(authors__in=[author])
    final_books = final_books and temp_books

…这就是我得到的:

AttributeError: 'NoneType' object has no attribute '_meta'

总的来说,我应该如何像在我的案例中那样在其ManyToMany字段包含一组给定对象的约束下查询模型?

ps:我发现了一些相关的SO问题,但找不到清晰的答案。任何好的指针也将有所帮助。谢谢。


阅读 446

收藏
2020-03-31

共1个答案

一尘不染

我找到了一个解决方案。但是,我认为效率可以提高。

# A sample set of authors
target_authors = set((author_1, author_2))

# To reduce the search space, first retrieve those books with just 2 authors.
candidate_books = Book.objects.annotate(c=Count('authors')).filter(c=len(target_authors))

# In each iteration, we filter out those books which don't contain one of the 
# required authors - the instance on the iteration.
for author in target_authors:
    candidate_books = candidate_books.filter(authors=author)

final_books = candidate_books
2020-03-31