green69
green69

Reputation: 1720

How to render an ordered dictionary in django templates?

I'm trying to learning django templates but it's not easy.
I have a certain views.py containing a dictionary to be rendered with a template. The dictionary is made of key-value pairs, where key are unique names and values are some values associated to those names. I render the dictionary in the following way:

return render_to_response('results.html', {'data': results_dict})

Now my problem is that in my template I need to display the names in alphabetical (or ASCIIbetical) order with the relatives values.
Actually in my template I have:

<table>
{% for key, value in data.items %}
    <tr>
        <td> {{ key }}: </td> <td> {{ value }} </td>
    </tr>
</table>

How can I render the data in sorted way? Many thanks.

Upvotes: 43

Views: 48933

Answers (4)

Rafael
Rafael

Reputation: 583

Although changing the code in the view is preferable, you could also use the dictsort template tag:

https://docs.djangoproject.com/en/stable/ref/templates/builtins/#std:templatefilter-dictsort

<table>
{% for key, value in data.items|dictsort:"0.lower" %}
    <tr>
        <td> {{ key }}: </td> <td> {{ value }} </td>
    </tr>
</table>

Upvotes: 29

In views.py (Python2):

return render_to_response('results.html',
    {'data': sorted(results_dict.iteritems())})

Or in views.py (Python3):

return render_to_response('results.html',
    {'data': sorted(results_dict.items())})

In template file:

{% for key, value in data.items() %}
    <tr>
        <td> {{ key }}: </td> <td> {{ value }} </td>
    </tr>
{% endfor %}

Upvotes: 60

tokenizer_fsj
tokenizer_fsj

Reputation: 1240

Another solution that worked very well for me and I think it's simplier. It uses OrderedDict() more info

In your views.py file add:

from collections import OrderedDict
def main(request):
    ord_dict = OrderedDict()
    ord_dict['2015-06-20'] = {}
    ord_dict['2015-06-20']['a'] = '1'
    ord_dict['2015-06-20']['b'] = '2'
    ord_dict['2015-06-21'] = {}
    ord_dict['2015-06-21']['a'] = '10'
    ord_dict['2015-06-21']['b'] = '20'
    return render(request, 'main.html', {'context': ord_dict})

Then in your template, you can do:

<table>
{% for key, value in context.items %}
    <tr>
        <td>{{ key }}</td>
        <td>{{ value.a }}</td>
        <td>{{ value.b }} </td>
    </tr>
{% endfor %}
</table>

This will return the keys of the dictionary in the same ordered that they were put in.

2015-06-20  1   2
2015-06-21  10  20

Upvotes: 16

Marek
Marek

Reputation: 405

Refreshing old question but it was something that I've spent some time on as a programming noobie. It kinds of expands Yuji Tomita's answer.

How to sort dictionary that looks like this:

{model_A_object: {key: value, ...},...}

by model_A_object.field.

I fill it with for loop, and use it to store some aggregation, etc., data for queryset that I pass to template.

I've managed to do this (with Shubuntu from #Django help) by:

    result = sorted(dictionary.iteritems(), key= lambda (k, v) :  (k.field, v))

Then in the template:

    {% for model_A_object, data in result %}
        {% for key, value in data.items %}
            ...
        {% endfor %}
    {% endfor %}

Clean and easy, yet not that simple to figure out for beginner. Notice, that first for loop has result not result.items as it's not dictionary anymore, but list of tuples.

Hope it helps someone.

Upvotes: 8

Related Questions