Opened 16 years ago

Closed 15 years ago

#9573 closed (wontfix)

template filter length() should call .count() on querysets

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

Description

Currently, django.template.defaultfilters.length() just calls len() on the passed in value. If the passed in value is queryset, len(queryset) of course ends up calling django.db.query.QuerySet().__len__(). This method ends ends up mapping the queryset into a list and calling len() on the resulting list (it will also of course use cached versions of the queryset list, but in all cases, the queryset gets expanded into an in-memory list).

I'd like to suggest that django.template.defaultfilters.length() instead do something like:

def length(value):
  """Returns the length of the value - useful for lists."""
  try:
     value.count()
  except:
     return len(value)

Change History (3)

comment:1 by Adrian Holovaty, 16 years ago

Resolution: wontfix
Status: newclosed

I don't think it's a good idea to couple the template system to our ORM.

comment:2 by miracle2k, 15 years ago

Component: Template systemDatabase layer (models, ORM)
Resolution: wontfix
Status: closedreopened
Version: 1.01.1

I just stumbled across this; For some reason I always assumed that {{ queryset|length }} would do a count() when possible.

Couldn't this be handled inside the ORM? I.e. len doing a count() query for as of yet unexecuted querysets, and continuing to fetch the remainder of the result if the queryset was already touched?

Clearly there is the downside of running an extra query in cases where the result is pulled later on anyway, but it may be worth the compromise.

comment:3 by Johannes Dollinger, 15 years ago

Resolution: wontfix
Status: reopenedclosed

The QuerySet API cannot guess your use-case, so there's len(qs) as well as qs.count() and bool(qs) as well as qs.exists() - Just use {{ queryset.count }} if that's what you want.

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