Django:注释不起作用? [英] Django: Annotation not working?
问题描述
我有两个模型,产品,与RatingEntry具有一对多关系:
I have two models, Product, which has a one-to-many relationship with a 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.
If I change a and b to lists, and concatenate them, the length works out to 210.
知道这是怎么回事吗?
推荐答案
我认为此行为是Django对象关系映射中的错误.如果您查看Django为查询生成的SQL,那么您将看到类似以下的内容:
I think this behaviour is a bug in Django's object-relationship mapping. If you look at the SQL that Django generates for your query, then you'll see something like this:
>>> 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
请注意,来自q1
的条件包含在查询的HAVING
子句中,但是来自q2
的条件已丢失.
Note that the condition from q1
is included in the HAVING
clause of the query, but the condition from q2
has been lost.
您可以通过以下方式构建查询来解决此问题:
You can work around the problem by building your query like this:
>>> 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
子句中.
Note that both conditions are now included in the HAVING
clause.
我建议您将此错误报告给Django开发人员. (如果无法解决,则至少应记录在案.)
I suggest that you report this to the Django developers as a bug. (If it can't be fixed, then at least it should be documented.)
这篇关于Django:注释不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!