Opened 4 years ago

Closed 4 years ago

#17311 closed Uncategorized (invalid)

bool(queryset) calls __len__ instead of __nonzero__

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


When testing the boolean value of a queryset (i.e. running "if queryset: ..."), the special attribute len is called which calls count() in the ORM. It should use the special attribute nonzero which would call the exists() method in the ORM.

Change History (1)

comment:1 Changed 4 years ago by lukeplant

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

Almost everything about this bug report is incorrect, I'm afraid :-) . When running if queryset, __nonzero__ is called, not __len__ (this is Python behaviour over which we have no control. It is true that __len__ is called indirectly in some situations in trunk, but not always). The special attribute __len__ does not call count(). Finally __nonzero__ already exists and does not and should not call exists().

The current behaviour is exactly as intended. The reason for this is to make the behaviour 1) predictable, and 2) behave nicely with several common usage patterns, such as:

if queryset:
   for obj in queryset

In short, the rule is you only get special queries (like exists() and count()) if you ask for them, because we cannot predict if you are going to want to use the QuerySet's result cache or not. All other constructs like bool() and len() and iter() evaluate the same query, and populate/use the same result cache where possible.

Note: See TracTickets for help on using tickets.
Back to Top