Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.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
Python Django:注释不起作用?_Python_Django_Annotations - Fatal编程技术网

Python Django:注释不起作用?

Python Django:注释不起作用?,python,django,annotations,Python,Django,Annotations,我有两个模型,Product,它与RatingEntry有一对多的关系: >>> product_entries = models.Products.objects.all() >>> annotated = product_entries.annotate(Count("ratingentry")) >>> len(annotated) 210 >>> a = annotated.filter(ratingentry__c

我有两个模型,Product,它与RatingEntry有一对多的关系:

>>> product_entries = models.Products.objects.all()
>>> annotated = product_entries.annotate(Count("ratingentry"))
>>> len(annotated)
210
>>> a = annotated.filter(ratingentry__count__lte = 10)
>>> b = annotated.filter(ratingentry__count__gt = 10)
>>> len(a)
10
>>> len(b)
200
>>> len(a | b)
10 //should be 210
如果我将a和b更改为列表,并将它们连接起来,则长度计算为210


知道这里发生了什么吗?

查询集不支持按位包含。Django不会引发错误,而是将其视为逻辑OR,并返回第一个计算值
True
。因为它们都是有效的查询集,所以总是返回第一个查询集


如果您想实际合并两个查询集,您要么需要将它们转换为列表,然后将其中一个扩展为另一个,要么使用类似itertools.chain的东西,但最终将得到一个生成器,它只能用于迭代。无论哪种方式,组合查询集都将禁止对这些查询集执行任何进一步的操作。

我认为这种行为是Django对象关系映射中的一个错误。如果查看Django为查询生成的SQL,您将看到如下内容:

>>> q1 = (Products.objects.annotate(num_ratings = Count('ratingentries'))
...       .filter(num_ratings__gt = 10))
>>> q2 = (Products.objects.annotate(num_ratings = Count('ratingentries'))
...       .exclude(num_ratings__gt = 10))
>>> print(str((q1 | q2).query))
SELECT `myapp_products`.`id`, COUNT(`myapp_ratingentries`.`id`) AS
`num_ratings` FROM `myapp_products` LEFT OUTER JOIN `myapp_ratingentries` ON
(`myapp_products`.`id` = `myapp_ratingentries`.`product_id`) GROUP BY
`myapp_products`.`id` HAVING COUNT(`myapp_ratingentries`.`id`) > 10
ORDER BY NULL
>>> q = Q(num_products__gt = 10) | ~Q(num_products__gt = 10)
>>> q3 = Products.objects.annotate(num_ratings = Count('ratingentries')).filter(q)
>>> print(str(q3.query))
SELECT `myapp_products`.`id`, COUNT(`myapp_ratingentries`.`id`) AS
`num_ratings` FROM `myapp_products` LEFT OUTER JOIN `myapp_ratingentries` ON
(`myapp_products`.`id` = `myapp_ratingentries`.`product_id`) GROUP BY
`myapp_products`.`id` HAVING (COUNT(`myapp_ratingentries`.`id`) > 10 OR NOT
(COUNT(`myapp_ratingentries`.`id`) > 10 )) ORDER BY NULL
请注意,
q1
中的条件包含在查询的
HAVING
子句中,但是
q2
中的条件已丢失

您可以通过如下方式构建查询来解决此问题:

>>> q1 = (Products.objects.annotate(num_ratings = Count('ratingentries'))
...       .filter(num_ratings__gt = 10))
>>> q2 = (Products.objects.annotate(num_ratings = Count('ratingentries'))
...       .exclude(num_ratings__gt = 10))
>>> print(str((q1 | q2).query))
SELECT `myapp_products`.`id`, COUNT(`myapp_ratingentries`.`id`) AS
`num_ratings` FROM `myapp_products` LEFT OUTER JOIN `myapp_ratingentries` ON
(`myapp_products`.`id` = `myapp_ratingentries`.`product_id`) GROUP BY
`myapp_products`.`id` HAVING COUNT(`myapp_ratingentries`.`id`) > 10
ORDER BY NULL
>>> q = Q(num_products__gt = 10) | ~Q(num_products__gt = 10)
>>> q3 = Products.objects.annotate(num_ratings = Count('ratingentries')).filter(q)
>>> print(str(q3.query))
SELECT `myapp_products`.`id`, COUNT(`myapp_ratingentries`.`id`) AS
`num_ratings` FROM `myapp_products` LEFT OUTER JOIN `myapp_ratingentries` ON
(`myapp_products`.`id` = `myapp_ratingentries`.`product_id`) GROUP BY
`myapp_products`.`id` HAVING (COUNT(`myapp_ratingentries`.`id`) > 10 OR NOT
(COUNT(`myapp_ratingentries`.`id`) > 10 )) ORDER BY NULL
请注意,这两个条件现在都包含在
HAVING
子句中


我建议你。(如果无法修复,那么至少应该记录下来。)

我认为这是不对的,我以前使用此运算符组合了QuerySet,结果成功了。例如:>>>a=models.Product.objects.filter(kind=“costs”)>>>b=models.Product.objects.filter(kind=“technology”)>>>len(a)90>>len(b)113>>>len(a | b)203>>你可以做
a=Q(ratingentry\uu count\uu lte=10);b=Q(比率入口计数=10);annotated.filter(a | b)
这个解释很有道理,我会尽量确保这不是我犯的愚蠢错误,并对此进行报告。