簡體   English   中英

Django多對多交叉過濾

[英]Django Many To Many intersection filtering

為了簡單起見,我們說我只有2個模型:Book,Author

class Author(models.Model):
    name = models.CharField(max_length='100')
    ...

class Book(models.Model):
    name = models.CharField(max_length='100')
    authors = models.ManyToManyField(Author)
    ...

我想使用作者列表過濾書籍。 我試圖做的是:

authors = [...] # a list of author objects
Books.objects.filter(authors__in=authors)

但是在這里,當我想要ANDed時,作者將被ORed。 有沒有辦法和多對多過濾?

你可以和一起Q對象一起:

q = Q()
for author in authors:
    q &= Q(authors=author)
Books.objects.filter(q)

要排除列表外具有作者的書籍,您可以將查詢限制為具有列表中作者數量的書籍:

Books.objects.annotate(count=Count('authors')).filter(count=len(authors)).filter(q)

更新:

根據評論,我認為要求是讓列表中至少有一位作者撰寫的所有書籍,但排除列表外任何作者的書籍。

因此,我們構建一個查詢集,選擇我們討厭的作者:

# this queryset will be embedded as a subquery in the next
bad_authors = Author.objects.exclude(name__in=['A1', 'A2'])

然后排除它們以找到我們想要的書籍:

# get all books without any of the bad_authors
Books.objects.exclude(authors__in=bad_authors)

這將返回除列表之外的人創作的所有書籍。 如果您還想排除那些沒有列出作者的內容,請添加另一個排除調用:

Books.objects.exclude(authors__in=bad_authors).exclude(authors=None)

這將只留下一個或多個好書的書籍!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM