3

示例模型:

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

class Author(models.Model):
    book = models.ForeignKey(Book)
    name = models.CharField(max_length=50)

和一些示例数据:

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

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

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

books = Book.objects.filter(author__name__icontains="111").filter(author__name__icontains="333")

它返回两本书 id: 3 和 4

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

4

2 回答 2

6

您可以结合 reduce 和 Q,请参阅The power of django's Q objects post。

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 )
于 2013-03-12T14:13:49.503 回答
0

这一个用于动态身份验证列表:

pk_list = qs.values_list('pk', flat=True)  # i.e [] or [1, 2, 3]

if len(pk_list) == 0:
    Book.objects.none()

else:
    q = None
    for pk in pk_list:
        if q is None:
            q = Q(pk=pk)
        else:
            q = q | Q(pk=pk)

    Book.objects.filter(q)
于 2014-08-02T10:33:49.677 回答