假设我们的Django模型定义如下:
class Tags(models.Model):
name = models.CharField(max_length=100, verbose_name = 'Tag name')
customers = models.ManyToManyField(Customers, related_name='tags', verbose_name = 'Refs to Customer')
class Customers(models.Model):
name = models.CharField(max_length=100, verbose_name='Display Name')
我想过滤包含所有标签的客户,排除所有标签。
include_all_tags = [1,2]
exclude_all_tags = [3, 4, 5]
但以下查询不起作用:
query = Customers.objects.all()
query = query.filter(tags__id__in=include_all_tags).annotate(c=Count('tags', distinct=True)).filter(c=len(include_all_tags))
query = query.exclude(tags__id__in=exclude_all_tags).annotate(c=Count('tags', distinct=True)).filter(c=len(exclude_all_tags))
SQL输出在这里,但是
( COUNT ( "core_customertag"."tag_id" ) = 2 AND COUNT ( "core_customertag"."tag_id" ) = 3 )
是同一别名表的计数!
SELECT
"core_customers"."id",
"core_customers"."name",
COUNT ( "core_customertag"."tag_id" ) AS "c"
FROM
"core_customers"
INNER JOIN "core_customertag" ON ( "core_customers"."id" = "core_customertag"."customer_id" )
WHERE
( "core_customertag"."tag_id" IN ( 1, 2 )
AND NOT ( "core_customers"."id" IN ( SELECT U1."customer_id" FROM "core_customertag" U1 WHERE U1."tag_id" IN ( 3, 4, 5 ) ) )
)
GROUP BY
"core_customers"."id"
HAVING
( COUNT ( "core_customertag"."tag_id" ) = 2 AND COUNT ( "core_customertag"."tag_id" ) = 3 )
预期:
SELECT
"core_customers"."id",
"core_customers"."name",
COUNT ( T1."tag_id" ) AS "c1"
COUNT ( T2."tag_id" ) AS "c2"
FROM
"core_customers"
INNER JOIN "core_customertag" T1 ON ( "core_customers"."id" = "core_customertag"."customer_id" )
INNER JOIN "core_customertag" T2 ON ( "core_customers"."id" = "core_customertag"."customer_id" )
WHERE
(
T1."tag_id" IN ( 1, 2 )
AND NOT ( T2."tag_id" IN ( 3, 4, 5 ) ) )
)
GROUP BY
"core_customers"."id"
HAVING
( COUNT ( T1."tag_id" ) = 2 AND COUNT ( T2."tag_id" ) = 3 )