Code

Opened 6 years ago

Closed 5 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: UI/UX:

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)

Attachments (0)

Change History (3)

comment:1 Changed 6 years ago by adrian

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

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

comment:2 Changed 5 years ago by miracle2k

  • Component changed from Template system to Database layer (models, ORM)
  • Resolution wontfix deleted
  • Status changed from closed to reopened
  • Version changed from 1.0 to 1.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 Changed 5 years ago by emulbreh

  • Resolution set to wontfix
  • Status changed from reopened to closed

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.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.