Opened 7 years ago

Closed 5 years ago

#11008 closed Bug (fixed)

dictsort and dictsortreversed template filters broken

Reported by: ionut bizau Owned by: nobody
Component: Template system Version: master
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:

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 7 years ago.

Download all attachments as: .zip

Change History (13)

Changed 7 years ago by ionut bizau

Attachment: dictsort.diff added

comment:1 Changed 7 years ago by Chris Beaven

Needs documentation: unset
Needs tests: set
Patch needs improvement: unset
Triage Stage: UnreviewedAccepted

comment:2 Changed 7 years ago by Alex Gaynor

Patch needs improvement: set

comment:3 Changed 7 years ago by ionut bizau

@Alex What's wrong with my patch?

comment:4 Changed 7 years ago by Alex Gaynor

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

comment:5 Changed 7 years ago by Chris Beaven

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 Changed 7 years ago by ionut bizau

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

comment:7 Changed 7 years ago by ionut bizau

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 Changed 7 years ago by Alex Gaynor

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 Changed 7 years ago by eronen

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 Changed 6 years ago by nathan

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

comment:11 Changed 5 years ago by Julien Phalip

Severity: Normal
Type: Bug

comment:12 Changed 5 years ago by Julien Phalip

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