Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django:多个多个值都包含queryset?_Django_Django Queryset - Fatal编程技术网

Django:多个多个值都包含queryset?

Django:多个多个值都包含queryset?,django,django-queryset,Django,Django Queryset,型号.py class Tag(BaseModel): name = models.CharField(max_length=256,unique=True) class Product(BaseModel): tag_set = models.ManyToManyField(Tag) 获得queryset products = Product.objects.filter( Q(tag_set__id__in=[12, 13, 14]), Q(is_acti

型号.py

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

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

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)产品——标签(id):12、13、14、15(O)
ex)产品——标签(id):12、13、15(X)
ex)产品——标签(id):12(X)

(抱歉英语不好)


如何实现此功能?

由于
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不使用索引,而是在索引列不唯一匹配时进行完全扫描。虽然我认为这是一个错误,但这意味着<代码> TaGyStSuxIdIyIn=……/代码>对于较大的表来说是非常低效的。如果使用
Q(tag_set_uid=12)| Q(tag_set_uid=13)| Q(tag_set_uid=14)|
,我可以推测这可能会有所不同,但我在三年前当Django开发人员时没有测试它(因为我没有想到它)。我们只是做了一个查询pr id来匹配。

另一种方法是继续对所有id应用过滤器,就像这样

all_products = Product.objects.all()
my_tags = [12, 13, 14]
for tag_id in my_tags:
    all_products = all_products.filter(tag_set__id=tag_id)

使用像这样的Q对象
过滤器(Q(tag=tag1)&Q(tag=tag2)&Q(tag=tag3))
如果@dnit不起作用,我不会感到惊讶。如果我没记错的话,
Q
对象将与外部联接中的每一行一起应用,并因此过滤掉所有内容。它可以工作,但不知道它会进行多少次查询?这会有点低效吗?三个,但三个简单的外部联接,没有半昂贵的分组。这可能相当有效。(尽管我建议您对不同的建议解决方案进行基准测试)我认为您的解决方案只包括带有标签的产品(确切地说是12、13、14),而不包括带有标签12、13、14、15的产品?带有标签12、13、14和15的产品也将包括在内,尽管标签15将被忽略。计数中仅包括匹配12、13和14的联接。其他匹配项将被忽略。如果不是这样的话,也很容易说匹配标签计数3(但我非常怀疑是这样的)它会进行多少次查询?看起来您只创建了一个查询请求?这里只有一个查询是的。生成的查询结构比另一个答案中的@dnit13稍微高级一些。他的是一个简单的左连接,重复了三次。我的是一个左连接组,执行一次。这两个查询可能依赖于不同的索引来高效执行。我的查询可能需要比dnit13更多的内存。