I see that the QuerySet class has 2 different methods that seem to serve the same purpose (unless I’m mistaken): .__nonzero__ and .exists. (Yes, I know that .__nonzero__ is used by bool.)
My question: Why do the 2 methods have different implementation if they both just check whether there’s any object in the queryset?
The Django documentation says about QuerySet.__nonzero__:
Note: Don’t use this if all you want to do is determine if at least
one result exists, and don’t need the actual objects. It’s more
efficient to use exists() (see below).
(I didn’t find anything insightful “below”.)
Why does QuerySet.__nonzero__ have a non-efficient implementation? Is it trying to achieve something different than .exists? What is the reason that the Django developers don’t do __nonzero__ = exists?
I think it’s because
existsis only efficient under certain circumstances.Imagine this common scenario if
__nonzero__had the “efficient” implementation.__nonzero__also evaluates the query and stores results in cache. That means all results are stored in memory.existsonly cares about 1 row, and doesn’t even instantiate a django object or even store its result in cache.It seems useful if you are only checking if something exists, and don’t need the data in any way.
Because
existsassumes you don’t care about the results. If__nonzero__calledexists, we’d have no results. Ifexistscalled__nonzero__, we’d collect results (potentially a lot) just to check if a row exists or not.Examples: