使用带有外键的Q对象定义django queryset

时间:2013-03-12 12:29:50

标签: 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)

以及一些示例数据:

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对象达到上述目标?

2 个答案:

答案 0 :(得分:4)

您可以将reduce和Q结合使用,请参阅The power of django’s Q objects帖子。

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 )

答案 1 :(得分: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)