﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
30473	len() and count() yield different results on randomly ordered QuerySet with annotation,	Tobias Kunze	nobody	"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

}}}
"	Bug	closed	Database layer (models, ORM)	dev	Normal	duplicate			Unreviewed	0	0	0	0	0	0
