Django过滤m2m字段,匹配给定的所有值

时间:2012-09-14 18:16:51

标签: python django

鉴于我是詹姆斯和尤金的作者。使用内置的__in QuerySet将过滤与James或Eugene匹配的m2m字段。但是,如果我只想要那些比赛,我该如何。

示例SetUp:给定

authors = Author.objects.filter(interests__in=['python','ruby'])
# [<Author: James>, <Author: Eugene>]

这是我为正常情况做出的查询。它将返回任何有詹姆斯或尤金或两者的书籍:

books = Book.objects.filter(authors__in=authors)
# [<Book: Book by James, Jack>, <Book: Book by Eugene>]

但目前如果我想找一本詹姆斯和尤金写的书,我将不得不做一个循环。

books = Book.objects
for author in authors:
    books = books.filter(authors=author)
# books [<Book: Book by James, Eugene>]

是否有一种优雅的方法可以直接对m2m字段进行过滤,以匹配两个给定的值。也许像是

books = Book.objects.filter(authors__match=authors)

2 个答案:

答案 0 :(得分:3)

您可以使用Q对象:

AND = lambda q, value: q & Q(authors_in=value)
Books.objects.filter(reduce(AND, authors, Q()))

如果你有一个作者列表而不仅仅是他们的id,你也可以和book_set结合在一起:

books = reduce(lambda q,a: q & a.book_set.all(), authors, Book.objects.none())

答案 1 :(得分:0)

你可以使用&amp;操作

# The list of authors you want to match
authors_pks = authors.values_list('pk', flat=True)

books = Book.objects

for pk in authors_pks:
    books &= Book.objects.filter(authors=pk)

print books.all()