-1

I want to pass a queryset which involves counting rows to a function without calling the database right away. For example, the following queryset is lazy and does not access the database until it is evaluated:

queryset = MyModel.objects.all()

I know from Django docs that len() forces the evaluation but what about count()? Does this hit the database right away?

queryset = MyModel.objects.all().count()

EDIT: I clarified my question

Martin Faucheux
  • 884
  • 9
  • 26

1 Answers1

0

I hope this will answer your query.

A count() call performs a SELECT COUNT(*) behind the scenes, so you should always use count() rather than loading all of the record into Python objects and calling len() on the result (unless you need to load the objects into memory anyway, in which case len() will be faster).

Note that if you want the number of items in a QuerySet and are also retrieving model instances from it (for example, by iterating over it), it’s probably more efficient to use len(queryset) which won’t cause an extra database query like count() would.

https://docs.djangoproject.com/en/3.0/ref/models/querysets/#count

Vishal Singh
  • 6,014
  • 2
  • 17
  • 33
  • 1
    Slightly off-piste from the original question, but interestingly the docs now explain a further nuance: `If the queryset has already been fully retrieved, count() will use that length rather than perform an extra database query` so `.count()` doesn't always hit the db. However if you used `.iterator()` over the queryset (rather than fully evaluating it) then the cache doesn't get filled in, so `.count()` will hit the database in that case. – sparrowt May 26 '22 at 13:35
  • can you include the docs link in comment? – Vishal Singh May 26 '22 at 14:42
  • https://docs.djangoproject.com/en/3.2/ref/models/querysets/#count (I can't edit the above comment any more) – sparrowt May 27 '22 at 12:02