#30473: len() and count() yield different results on randomly ordered QuerySet
with
annotation
-------------------------------------+-------------------------------------
Reporter: Tobias | Owner: nobody
Kunze |
Type: Bug | Status: new
Component: Database | Version: 2.2
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I found myself with a QuerySet that is ordered randomly, and found that
`qs.count()` and `len(qs)` return different results.
Additionally, since `len(qs)` sets some kind of result cache, any
`qs.count()` called after `len(qs)` will return the same result as
`len(qs)`, which is an additional source of inconsistency and confusion.
I'd argue that at the very least `len(qs)` should not be able to change
the output of `qs.count()`.
Minimal example here:
{{{
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=20)
class Review(models.Model):
article = models.ForeignKey(to=Article, on_delete=models.CASCADE)
}}}
{{{
>>> from django.db import models
>>> a = Article.objects.create(title='Article')
(0.015) INSERT INTO "bar_article" ("title") VALUES ('Article');
args=['Article']
>>> Review.objects.create(article=a)
(0.026) INSERT INTO "bar_review" ("article_id") VALUES (1); args=[1]
<Review: Review object (1)>
>>> Review.objects.create(article=a)
(0.014) INSERT INTO "bar_review" ("article_id") VALUES (1); args=[1]
<Review: Review object (2)>
>>> result =
Article.objects.annotate(review_count=models.Count('review')).order_by('?')
>>> result.count()
(0.000) SELECT COUNT(*) FROM (SELECT "bar_article"."id" AS Col1,
COUNT("bar_review"."id") AS "review_count" FROM "bar_article" LEFT OUTER
JOIN "bar_review" ON ("bar_article"."id" = "bar_review"."article_id")
GROUP BY "bar_article"."id") subquery; args=()
1
>>> len(result)
(0.001) SELECT "bar_article"."id", "bar_article"."title",
COUNT("bar_review"."id") AS "review_count" FROM "bar_article" LEFT OUTER
JOIN "bar_review" ON ("bar_article"."id" = "bar_review"."article_id")
GROUP BY "bar_article"."id", "bar_article"."title", RANDOM() ORDER BY
RANDOM() ASC; args=()
2
>>> result.count()
2
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/30473>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/047.77a6bf9cb3f8a634b464d0b03ed8dd58%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.