How to access multidimensional dictionary on Django template - python

I am trying to access a multidimensional dictionary in a Django template. I am able to view first level keys, but since second level keys I cannot see anything. In example dictionary is composed in this way:
dictionary = {}
dictionary[first_level] = {}
dictionary[first_level][second_level] = {}
...
and so on
From Django template I use:
{% for flk in dict %}
<!-- Using nested for from the following, no output is shown -->
{% for slk in dict.flk %}
<th>First level key : {{ flk }} Second level key : {{ slk }}</th>
{% endfor %}
<!-- -->
{% endfor %}
Have I to use a model or can I do it using this dictionary?
Thanks

I've found the solution on this page
Basically the code becomes
{% for flk, flv in dict.items %}
{% for slk, slv in flv.items %}
<th>First level key {{ flk }} Second level key {{ slk }}</th>
{% endfor %}
{% endfor %}
where each dictionary is decomposed in keys (flk, slk) and values (flv, slv).

Related

Django ListView, split list into categories in template, by modifying a "current_category" variable

I don't really know how to phrase my question, but what I'm trying to do is add a title between items to split them into obvious categories on my template. I would like to do this:
{# set variable "current_category" to an empty value first #}
{% for item in items %}
{% if item.category != current_category %}
{{ current_category = item.category }} {# <-- How to do that? #}
<h1>{{ item.category }}</h1>
{% endif %}
<p>{{ item.name }}</p>
{% endfor %}
Then end up with:
<h1>Cat 1</h1>
<p>item</p>
<p>item</p>
...
<h1>Cat 2</h1>
<p>item</p>
..
I saw on similar answers that there are things called custom filters and simple tags but it seems really complicated for something very simple. Is this really the only way to do that?
NOTE: I already ordered the items by category of course
I think you're looking for Django's regroup template tag, which does exactly what you're asking for.
{% regroup items by category as grouped_items %}
{% for category, item_list in grouped_items %}
<h1>{{ category }}</h1>
{% for item in item_list %}
<p>{{ item.name }}</p>
{% endfor %}
{% endfor %}

Django Template Tag Loop dictionary variable

I've reading all the template tags posts regarding the loop variable in the key. Apparently Django does not support loop variable in key and I am not sure how to use the custom template tag.
I wanted to display something like this, but how can I achieve this with {% for i in mData %} loop ?
{{ mData.0.name }}
{{ mData.1.name }}
{{ mData.2.name }}
{{ mData.0.age }}
{{ mData.1.age }}
{{ mData.2.age }}
mData is a list of dictionaries.
mData = { "name":"alex", "age":"12"},{"name":"amy","age":"14"} ...
Considering your data is in a list of dictionaries such as:
my_data = [{"name" : "abc" , "age":20,...}, {} , {}...]
You can access all attributes of each dictionary in your template this way:
{% for dict in my_data %}
<!-- Here dict would be each of the dictionary in my_data -->
<!-- You can access elements of dict using dot syntax, dict.property -->
{{ dict.name }}, {{ dict.age }}, ... {{ dict.property }}
{% endfor %}
Reference links: Django templating language
If you want to structure your elements in the order you specifed, you can do something like this:
Name List:
{% for dict in my_data %}
my_data.name
{% endfor %}
Age List:
{% for dict in my_data %}
my_data.age
{% endfor %}
...
Prpoerty List:
{% for dict in my_data %}
my_data.property
{% endfor %}
Django template tags are intentionally very lightweight so that you don't put too much code into the template itself. If you need to do something complicated like loop over every other entry in the database, you should be setting that up in views.py instead of the template.
For the scenario you described, all you need to do is loop over the list of objects:
{% for data in datas %}
{{ data.name }}
{% endfor %}
{% for data in datas %}
{{ data.age }}
{% endfor %}
This solved the problem for me
{% for d in mData %}
{{ d.name }} {{ d.age }}
{% endfor %}
{% for k, v in mData.items %}
{{ k }} {{ v }}
by the way, PEP8 suggest we name the variable as lower + _, but not hump like javascript or other languages.

accessing a list of tuples in html

I have a list of tuples called top_5 which are the top 5 users usernames and their corresponding post count.
This is a list that has 5 items and each item has 2 indexes.
{% for user in top_5 %}
{{ user }}
{% endfor %}
returns the user and his post count but is there a way I can get them separately?
Is this a Django template? You can access index values in Django template using the dot notation:
{% for user in top_5 %}
{{ user.0 }} {{ user.1 }}
{% endfor %}
And as mentioned in the comments, unpacking the tuples is also an option:
{% for username, post_count in top_5 %}
{{ username }} {{ post_count }}
{% endfor %}

How can I Iterate through the same dictionary multiple times in a Django template?

I have a dictionary called categories. And I just want to iterate through this dictionary twice in a Django template. Below is my code:
<div class="first">
{% for category in categories %}
<li class="{{category.name}}">{{category.name}</li>
{% endfor %}
</div>
<div class="lenDict">
<h2>{{categories|length}}</h2>
</div>
<div class="second">
{% for category in categories %}
{% for facet in allFacets %}
{% if category.name == facet.category %}
<p id="{{facet.id}}">{{facet.facet}}</p>
{% endif %}
{% endfor %}
{% endfor %}
</div>
When I do it like this the first loop under the div first works fine.
But when it comes to the second loop under the div second it gives no result.
Also the code under the div lenDict also gives no result.
Are there any limitations in Django templates that we cannot iterate the same dictionary twice?
Any help will be appreciated.
To iterate through an entire dict in Python, you should use .iteritems(). It creates a new iterator over the (key, value) pairs of the dict. You could also use items() if you wanted a list of items instead.
<div class="first">
{% for key, value in categories.iteritems() %}
<li class="{{ key }}">{{ value }}</li>
{% endfor %}
</div>
<div class="lenDict">
<h2>{{ categories|length }}</h2>
</div>
<div class="second">
{% for key, value in categories.iteritems() %}
{% for facet in allFacets %}
{% if key == facet.category %}
<p id="{{facet.id}}">{{facet.facet}}</p>
{% endif %}
{% endfor %}
{% endfor %}
</div>
Note that your dict will be unordered. If you want to preserve the orders of the keys, use an OrderedDict.
So I think this works. I think your issue is facet.category. Is this a fk? because if this is a fk the if statement should be
{% if category.id == facet.category %}
In python iterators don't need to be reset, so I don't think you have to reset your iterators in the tamplate.
Note: I would leave this is in a comment but rep isn't high enough.

django regroup grouper name as choices verbose name

Taking simple regroup example from Django documentation:
{% regroup cities by country as country_list %}
<ul>
{% for country in country_list %}
<li>{{ country.grouper }}
<ul>
{% for item in country.list %}
<li>{{ item.name }}: {{ item.population }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
If country.grouper is a Char field declared in model with choices=CHOICES_FIELD, how can I display it's verbose name in template ? Normally i would take Model.get_FOO_display but country.grouper.get_country_list_display of course will not work.
Is custom template tag only choice ?
You simply have to look at it the other way around!
Use get_FOO_display as the grouping field.
{% regroup cities by get_country_display as country_list %}
{{ country.grouper }} will now display the value fields from the
choices set rather than the keys.
(taken verbatim from djangodocs)

Categories

Resources