Opened 10 years ago

Last modified 10 years ago

#23662 closed Cleanup/optimization

QuerySet __nonzero__, __len__ cause queryset evaluation — at Initial Version

Reported by: Alexey Smishlayev Owned by: nobody
Component: Database layer (models, ORM) Version: 1.7
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: yes

Description

Current implementation:
https://github.com/django/django/blob/master/django/db/models/query.py
class QuerySet(object):

...
def nonzero(self):

self._fetch_all()
return bool(self._result_cache)

...
def len(self):

self._fetch_all()
return len(self._result_cache)

These methods call self._fetch_all(), thus evaluating the queryset. Although, this behaviour is documented (https://docs.djangoproject.com/en/1.7/ref/models/querysets/#when-querysets-are-evaluated), it is not obvious.

It seems logical to evaluate queryset, when casting it to a list() or iterating over it, but these particular cases have nothing to do with the queryset contents. There exist specific lazy methods (QuerySet.exists() and QuerySet.count() respectively) which, IMHO, should be used for the magic method implementation.

If I already have fetched the results of a queryset, I'm okay to call len() on them, but if they haven't been retrieved yet, I'd rather use SQL COUNT() instead. That is exactly, what QuerySet.count() does. The same goes for the nonzero() and exists().

Change History (1)

by Alexey Smishlayev, 10 years ago

Attachment: Fix#23662.patch added
Note: See TracTickets for help on using tickets.
Back to Top