使用带有外键的 Q 对象定义 django 查询集

Luk*_*ara 3 django django-queryset django-q

示例模型:

class Book(models.Model):
    title = models.TextField()

class Author(models.Model):
    book = models.ForeignKey(Book)
    name = models.CharField(max_length=50)
Run Code Online (Sandbox Code Playgroud)

和一些示例数据:

Book:
id  title
1   test111
2   test222
3   test333
4   test444

Author:
book_id  name
1        test111
1        test222
2        test222
2        test333
3        test111
3        test333
4        test111
4        test333
Run Code Online (Sandbox Code Playgroud)

我想获取所有作者姓名包含“111”和“333”的书(因此所有至少有 2 个作者的书:第一个名称为 111,第二个名称为 333)

我可以通过使用链查询来达到这个目标:

books = Book.objects.filter(author__name__icontains="111").filter(author__name__icontains="333")
Run Code Online (Sandbox Code Playgroud)

返回两本书,id 为:3 和 4

有没有办法通过使用 Q 对象来达到上述目标?

dan*_*era 6

您可以将 reduce 和 Q 结合使用,请参阅django 的 Q 对象的威力一文

from django.db.models import Q
import operator
auths = [ "111", "333" ]
query = reduce(operator.and_, [ Q(author__name__icontains=x) for x in auths ] )
books = Book.objects.filter( query )
Run Code Online (Sandbox Code Playgroud)