Django | sort dict in template

I want to print a dictionary sorted by key. Sorting keys is easy to view by simply placing the keys in a list and then sorting the list. How can I scroll the keys in a template and then get the value from the dictionary.

{% for company in companies %} {% for employee, dependents in company_dict.company.items %} {% endfor %} {% endfor %} 

(Just made an example ...) The part that does not work is the part of "company_dict.company.items". I need a "company" to be a valuable company. Right now, prat is looking for a key called "company", not the value of the "company" from the cycle above.

I do a bit of processing to put the dictionary of dictionaries together. Changing the data layout is not really an option. I believe that the right approach is to write a template tag, I just wanted to find out if there was a built-in method that I missed.

+8
python django
source share
6 answers

custom filter template will do the trick.

 from django import template register = template.Library() def dict_get(value, arg): #custom template tag used like so: #{{dictionary|dict_get:var}} #where dictionary is duh a dictionary and var is a variable representing #one of it keys return value[arg] register.filter('dict_get',dict_get) 

more about custom template filters: http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags

in your example you would do:

 {% for employee, dependents in company_dict|company %} 
+3
source share

create a custom filter that looks like this:

 from django import template from django.utils.datastructures import SortedDict register = template.Library() @register.filter(name='sort') def listsort(value): if isinstance(value, dict): new_dict = SortedDict() key_list = sorted(value.keys()) for key in key_list: new_dict[key] = value[key] return new_dict elif isinstance(value, list): return sorted(value) else: return value listsort.is_safe = True 

then in your template you should call it using:

 {% for key, value in companies.items|sort %} {{ key }} {{ value }} {% endfor %} 

You can get a sorted dict with the key.

+19
source share

This last solution was very helpful to me. I am using Django 1.6.2, and it seems to convert the dict to a list with the key as the first element of this list, and the content is the second. Therefore, even when I go into the recorder, he sees it as a list. So I redid the above to look like this, and this works for me:

 @register.filter(name='sort') def listsort(value): if isinstance(value, list): return sorted(value, key=lambda k:k[0]) else: return value 
+1
source share

for some reasone Turikumwe filter didn’t work for me (python3.4, Django 1.7), so I rewrite it to return a list of tuples instead of SertedDict or OrderedDict :

 @register.filter(name='sort') def listsort(value): if isinstance(value, dict): a = [] key_list = sorted(value.keys()) for key in key_list: a.append((key, value[key])) return a elif isinstance(value, list): return sorted(value) else: return value listsort.is_safe = True 

Therefore, in the template we do not need to receive .items

 {% for key, value in companies|sort %} {{ key }} {{ value }} {% endfor %} 
0
source share

Turikumwe's answer forced me to close, but did not work for my environment: python3 and Django 1.10.

I found that the filter is called using

 {% for key, value in companies.items|sort %} {{ key }} {{ value }} {% endfor %} 

actually leads to an ItemsView, not a dict. (I suspect this is a problem with python 2 vs 3). Given ItemView, the answer is even simpler

 from django import template from django.utils.datastructures import ItemsView register = template.Library() @register.filter(name='sort') def listsort(value): if isinstance(value, ItemsView) or isinstance(value, list): return sorted(value) else: return value 
0
source share

You can use django dictsort or dictsortreversed .

 {% for user in list_users|dictsort:'created_at' %} {{user.username}} - {{user.created_at}} {% endfor %} 

or

 {% for user in list_users|dictsortreversed:'created_at' %} {{user.username}} - {{user.created_at}} {% endfor %} 
0
source share

All Articles