Opened 15 years ago

Closed 13 years ago

#11008 closed Bug (fixed)

dictsort and dictsortreversed template filters broken

Reported by: ionut bizau Owned by: nobody
Component: Template system Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Using dictsort or dictsortreversed template filters for a list of dictionaries which contain dates will break if some of the dates are None, even if the sort field is not one of the date fields! This happens when the list contains at least two dictionaries for which the sort keys are equal.

Example:

In [1]: from django.template import defaultfilters

In [3]: from datetime import datetime

In [4]: defaultfilters.dictsort([{'a': 1, 'b': datetime.now()}, {'a': 2, 'b': None}, {'a': 1, 'b': None}], "a")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/XXX/<ipython console> in <module>()

/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/django/template/defaultfilters.pyc in dictsort(value, arg)
    470     var_resolve = Variable(arg).resolve
    471     decorated = [(var_resolve(item), item) for item in value]
--> 472     decorated.sort()
    473     return [item[1] for item in decorated]
    474 dictsort.is_safe = False

TypeError: can't compare datetime.datetime to NoneType

My patch fixes this problem for both dictsort and dictsortreversed.

Attachments (1)

dictsort.diff (821 bytes ) - added by ionut bizau 15 years ago.

Download all attachments as: .zip

Change History (13)

by ionut bizau, 15 years ago

Attachment: dictsort.diff added

comment:1 by Chris Beaven, 15 years ago

Needs tests: set
Triage Stage: UnreviewedAccepted

comment:2 by Alex Gaynor, 15 years ago

Patch needs improvement: set

comment:3 by ionut bizau, 15 years ago

@Alex What's wrong with my patch?

comment:4 by Alex Gaynor, 15 years ago

It should use the key argument, not the cmp one, as cmp has been deprecated. It also lacks tests.

comment:5 by Chris Beaven, 15 years ago

Where do the Python docs say cmp has been deprecated? At the very least, they show that key was introduced in 2.4 so we can't rely on that.

comment:6 by ionut bizau, 15 years ago

OK. I was afraid to use key for compatibility reasons (Python 2.3 doesn't support it). Will look into the tests.

comment:7 by ionut bizau, 15 years ago

It's only been deprecated since 2.6. So it's a question of whether Django needs to run on 2.3 or not. Also, seems cmp will be removed from 3.0. Does Django support 3.0 officially?

comment:8 by Alex Gaynor, 15 years ago

Oh, I hadn't realized 2.3 didn't have it, though Django 1.1 will support 2.3, this almost certainly won't get in until 1.2 at which point 2.3 will no longer be supported.

comment:9 by eronen, 14 years ago

The patch here fixes another problem in dictsort, too: unlike Python's sort,
it's not stable sort (doesn't preserve the order when the sorting key is the same).
See ticket #12110.

comment:10 by nathan, 14 years ago

I've run into this on numerous occasions. Any idea on when this'll be applied?

comment:11 by Julien Phalip, 13 years ago

Severity: Normal
Type: Bug

comment:12 by Julien Phalip, 13 years ago

Easy pickings: unset
Resolution: fixed
Status: newclosed

This is actually working fine now. Probably fixed in [15316].

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