Merge pull request #692 from dnmvisser/dictsort_reverse

Dictsort reverse
This commit is contained in:
David Lord 2017-07-08 09:10:33 -07:00 committed by GitHub
commit 711ad9dc21
3 changed files with 25 additions and 16 deletions

View File

@ -30,6 +30,7 @@ Version 2.10
``gt``, ``ge``. (`#665`_)
- ``import`` statement cannot end with a trailing comma. (`#617`_, `#618`_)
- ``indent`` filter will not indent blank lines by default. (`#685`_)
- Add ``reverse`` argument for ``dictsort`` filter. (`#692`_)
.. _#469: https://github.com/pallets/jinja/pull/469
.. _#475: https://github.com/pallets/jinja/pull/475
@ -38,6 +39,7 @@ Version 2.10
.. _#618: https://github.com/pallets/jinja/pull/618
.. _#665: https://github.com/pallets/jinja/pull/665
.. _#685: https://github.com/pallets/jinja/pull/685
.. _#692: https://github.com/pallets/jinja/pull/692
Version 2.9.6
-------------

View File

@ -203,7 +203,7 @@ def do_title(s):
if item])
def do_dictsort(value, case_sensitive=False, by='key'):
def do_dictsort(value, case_sensitive=False, by='key', reverse=False):
"""Sort a dict and yield (key, value) pairs. Because python dicts are
unsorted you may want to use this function to order them by either
key or value:
@ -213,6 +213,9 @@ def do_dictsort(value, case_sensitive=False, by='key'):
{% for item in mydict|dictsort %}
sort the dict by key, case insensitive
{% for item in mydict|dictsort(reverse=true) %}
sort the dict by key, case insensitive, reverse order
{% for item in mydict|dictsort(true) %}
sort the dict by key, case sensitive
@ -224,15 +227,19 @@ def do_dictsort(value, case_sensitive=False, by='key'):
elif by == 'value':
pos = 1
else:
raise FilterArgumentError('You can only sort by either '
'"key" or "value"')
raise FilterArgumentError(
'You can only sort by either "key" or "value"'
)
def sort_func(item):
value = item[pos]
if isinstance(value, string_types) and not case_sensitive:
value = value.lower()
if not case_sensitive:
value = ignore_case(value)
return value
return sorted(value.items(), key=sort_func)
return sorted(value.items(), key=sort_func, reverse=reverse)
@environmentfilter

View File

@ -45,16 +45,16 @@ class TestFilter(object):
)
assert tmpl.render(given='yes') == 'no|False|no|yes'
def test_dictsort(self, env):
tmpl = env.from_string(
'{{ foo|dictsort }}|'
'{{ foo|dictsort(true) }}|'
'{{ foo|dictsort(false, "value") }}'
)
out = tmpl.render(foo={"aa": 0, "b": 1, "c": 2, "AB": 3})
assert out == ("[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]|"
"[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]|"
"[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]")
@pytest.mark.parametrize('args,expect', (
('', "[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]"),
('true', "[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]"),
('by="value"', "[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]"),
('reverse=true', "[('c', 2), ('b', 1), ('AB', 3), ('aa', 0)]")
))
def test_dictsort(self, env, args, expect):
t = env.from_string('{{{{ foo|dictsort({args}) }}}}'.format(args=args))
out = t.render(foo={"aa": 0, "b": 1, "c": 2, "AB": 3})
assert out == expect
def test_batch(self, env):
tmpl = env.from_string("{{ foo|batch(3)|list }}|"