Django:多个ManyToMany值ALL包含查询集?

时间:2017-01-06 07:37:19

标签: django django-queryset

models.py

class Tag(BaseModel):
    name = models.CharField(max_length=256,unique=True)

class Product(BaseModel):
    tag_set = models.ManyToManyField(Tag)

获取查询集,

products = Product.objects.filter(
    Q(tag_set__id__in=[12, 13, 14]),
    Q(is_active=True),
)

此查询集将包含标签的ID为12或13或14中的任何一个的产品。 我只想要所有标签包含12,13,14( ALL

的产品

ex)product - tags(id):12,13,14,15(O)
ex)product - tags(id):12,13,15(X)
ex)product - tags(id):12(X)

(抱歉英语不好)

我该如何实现?

2 个答案:

答案 0 :(得分:0)

由于Tag.name是唯一的,因此您可以使用group by和count进行过滤。即。

products = Product.objects.filter(
    Q(tag_set__id__in=[12, 13, 14])), Q(is_active=True)).annotate(
        matching_tags_count=models.Count("tag_set__id").filter(
            matching_tags_count=3)

<强>更新 根据我的经验,postgreSQL不使用索引,而是在索引列未唯一匹配时执行完整扫描。虽然我认为这是一个错误,但这意味着tag_set__id__in=[...]对于较大的表来说效率非常低。我可以推测,如果使用Q(tag_set__id=12)|Q(tag_set__id=13)|Q(tag_set__id=14)|代替它可能会有所不同,但是当我三年前成为Django开发人员时,我没有测试它(因为我没有想到它)。我们最终只做了一个查询pr id来匹配。

答案 1 :(得分:0)

另一种方法是继续为你的所有id应用过滤器,

EXECUTE msdb.dbo.sysmail_delete_log_sp  
    @logged_before = GETDATE()-4 ;  
GO