列表中每个*项目的Django过滤器查询集__in

假设我有以下型号

class Photo(models.Model):

tags = models.ManyToManyField(Tag)

class Tag(models.Model):

name = models.CharField(max_length=50)

在一个视图中,我有一个带有活动过滤器的列表,称为category。我想过滤所有具有类别标签的照片对象。

我试过了:

Photo.objects.filter(tags__name__in=categories)

但这匹配类别中的任何项目,而不是所有项目。

因此,如果类别是[‘holiday’,’summer’],我希望Photo带有假日和夏季标签。

能做到吗?

回答:

正如jpic和sgallen在评论中所建议的那样,可以.filter()为每个类别添加一个选项。每filter增加一个,就会添加更多的联接,这对于少量的类别来说应该不是问题。

有聚合 方法。对于大量类别,此查询将更短,甚至更快。

您还可以选择使用自定义查询。

一些例子

测试设置:

class Photo(models.Model):

tags = models.ManyToManyField(‘Tag’)

class Tag(models.Model):

name = models.CharField(max_length=50)

def __unicode__(self):

return self.name

In [2]: t1 = Tag.objects.create(name=’holiday’)

In [3]: t2 = Tag.objects.create(name=’summer’)

In [4]: p = Photo.objects.create()

In [5]: p.tags.add(t1)

In [6]: p.tags.add(t2)

In [7]: p.tags.all()

Out[7]: [, ]

使用链接过滤器方法:

In [8]: Photo.objects.filter(tags=t1).filter(tags=t2)

Out[8]: []

结果查询:

In [17]: print Photo.objects.filter(tags=t1).filter(tags=t2).query

SELECT “test_photo”.”id”

FROM “test_photo”

INNER JOIN “test_photo_tags” ON (“test_photo”.”id” = “test_photo_tags”.”photo_id”)

INNER JOIN “test_photo_tags” T4 ON (“test_photo”.”id” = T4.”photo_id”)

WHERE (“test_photo_tags”.”tag_id” = 3 AND T4.”tag_id” = 4 )

请注意,每个都为查询filter添加了更多内容JOINS。

使用注释 方法:

In [29]: from django.db.models import Count

In [30]: Photo.objects.filter(tags__in=[t1, t2]).annotate(num_tags=Count(‘tags’)).filter(num_tags=2)

Out[30]: []

结果查询:

In [32]: print Photo.objects.filter(tags__in=[t1, t2]).annotate(num_tags=Count(‘tags’)).filter(num_tags=2).query

SELECT “test_photo”.”id”, COUNT(“test_photo_tags”.”tag_id”) AS “num_tags”

FROM “test_photo”

LEFT OUTER JOIN “test_photo_tags” ON (“test_photo”.”id” = “test_photo_tags”.”photo_id”)

WHERE (“test_photo_tags”.”tag_id” IN (3, 4))

GROUP BY “test_photo”.”id”, “test_photo”.”id”

HAVING COUNT(“test_photo_tags”.”tag_id”) = 2

ANDed Q对象不起作用:

In [9]: from django.db.models import Q

In [10]: Photo.objects.filter(Q(tags__name=’holiday’) & Q(tags__name=’summer’))

Out[10]: []

In [11]: from operator import and_

In [12]: Photo.objects.filter(reduce(and_, [Q(tags__name=’holiday’), Q(tags__name=’summer’)]))

Out[12]: []

结果查询:

In [25]: print Photo.objects.filter(Q(tags__name=’holiday’) & Q(tags__name=’summer’)).query

SELECT “test_photo”.”id”

FROM “test_photo”

INNER JOIN “test_photo_tags” ON (“test_photo”.”id” = “test_photo_tags”.”photo_id”)

INNER JOIN “test_tag” ON (“test_photo_tags”.”tag_id” = “test_tag”.”id”)

WHERE (“test_tag”.”name” = holiday AND “test_tag”.”name” = summer )

以上是 列表中每个*项目的Django过滤器查询集__in 的全部内容, 来源链接: utcz.com/qa/415670.html

回到顶部