5

私がジェームズとユージーンの著者であることを考えると。組み込みの__inQuerySetを使用すると、JamesまたはEugeneのいずれかに一致するm2mフィールドがフィルタリングされます。しかし、それらだけが両方に一致するようにしたい場合はどうすればよいでしょうか。

セットアップ例:

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

これが私が通常の状態に対して行ったクエリです。Jamesまたは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)
4

2 に答える 2

3

Q オブジェクトを使用できます。

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

ID だけでなく Author のリストがある場合は、book_set を AND で結合することもできます。

books = reduce(lambda q,a: q & a.book_set.all(), authors, Book.objects.none())
于 2012-09-14T18:27:31.183 に答える
0

&演算子を使用できます

# 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()
于 2012-09-14T18:42:50.807 に答える