Opened 9 years ago
Closed 9 years ago
#25670 closed Bug (fixed)
`dictsort` does not work when `arg` parameter is numeric
Reported by: | Andrew Kuchev | Owned by: | Andrew Kuchev |
---|---|---|---|
Component: | Template system | Version: | 1.8 |
Severity: | Normal | Keywords: | template filter dictsort |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
According to dictsort
documentation, it orders given list of dictionaries, using arg
as property in each dictionary:
@register.filter(is_safe=False) def dictsort(value, arg): """ Takes a list of dicts, returns that list sorted by the property given in the argument. """ try: return sorted(value, key=Variable(arg).resolve) except (TypeError, VariableDoesNotExist): return ''
However, it is not possible to order list of dictionaries by a numeric key. Let's consider the following test case:
def test_sort_list_of_tuple_like_dicts(self): data = [{'0': 'a', '1': '42'}, {'0': 'c', '1': 'string'}, {'0': 'b', '1': 'foo'}] sorted_data = dictsort(data, '0') self.assertEqual([{'0': 'a', '1': '42'}, {'0': 'b', '1': 'foo'}, {'0': 'c', '1': 'string'}], sorted_data)
This test fails with the following message:
Traceback (most recent call last): File ".../django/tests/template_tests/filter_tests/test_dictsort.py", line 50, in test_sort_list_of_tuple_like_dicts {'0': 'c', '1': 'string'}], sorted_data) AssertionError: Lists differ: [{'0': 'a', '1': '42'}, {'0': 'b', '1': 'foo'}, {'0': 'c', '1': 'string'}] != [{'0': 'a', '1': '42'}, {'0': 'c', '1': 'string'}, {'0': 'b', '1': 'foo'}] First differing element 1: {'0': 'b', '1': 'foo'} {'0': 'c', '1': 'string'} - [{'0': 'a', '1': '42'}, {'0': 'b', '1': 'foo'}, {'0': 'c', '1': 'string'}] + [{'0': 'a', '1': '42'}, {'0': 'c', '1': 'string'}, {'0': 'b', '1': 'foo'}]
The dictsort
uses sorted
function with key=Variable(arg).resolve
. When arg
is '0'
, key
function should behave like operator.itemgetter('0')
, but Variable('0').resolve(context)
returns 0
regardless of given context
.
There are five usages of dictsort
with "0"
as arg
in debug.py
As mentioned by bmispelon, this may be some kind of regression in Django 1.3.
Change History (8)
comment:1 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 9 years ago
Status: | new → assigned |
---|
comment:4 by , 9 years ago
I'm not sure about this. It seems like the old behavior was somewhat accidental. Having a filter called "dictsort" work on a list of lists seems a bit odd and unintuitive. Maybe we should ask for other opinions on the django-developers mailing list. Maybe there is a common third-party filter that would do the job that we could add to builtins.
comment:5 by , 9 years ago
After some further thought, I changed my mind given the fact that dictsort doesn't work with numeric string keys. That's definitely a bug that should be fixed.
comment:6 by , 9 years ago
Patch needs improvement: | set |
---|
I left comments for improvement on the pull request.
comment:7 by , 9 years ago
Patch needs improvement: | unset |
---|
This ticket is a spinoff of #25646.