How to go through two loops in django templates - python

Can anyone tell me what am I doing wrong in this code:
{% for dayName in data %}
<tr>
<td>{{ dayName }}</td>
{% for value in data.dayName %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
data is an object containing arrays, for an instance:
data['Sunday'] = [1 ,2 ,3]
And all what I want to do is create two loops through that object.
I will be thankful for each form of help,
Thanks in advance

dayName is a variable not the key itself. data.dayName is interpreted as data['dayName'], that's why you're not getting the right results.
Instead, you can do:
{% for dayName, vals in data.items %}
<tr>
<td>{{ dayName }}</td>
{% for value in vals %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}

Related

Iterating over a list from an object in Django template

I am trying to iterate over a list that is below an object in a Django template.
Unfortunately I am not getting anywhere.
This is the object:
{'Value1': [8, 5, 4, 7, 4, 5], 'Value2': [], 'Value3': []}
I am doing in the template something like:
{% for entry in data %}
<tr>
<td>{{ entry }}</td>
<td>{{ entry.0 }}</td>
</tr>
{% endfor %}
or
{% for entry in data %}
<tr>
<td>{{ entry }}</td>
{% for i in entry %}
<td>{{ i }}</td>
{% endfor %}
</tr>
{% endfor %}
But all I am getting is just the first letter of the key.
You have to look for both - keys and values in dict's items:
{% for key, value_list in data.items %}
<tr>
<td>{{ entry }}</td>
{% for value in value_list %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
Did you try iterating over the items in your dict, like so?
{% for key, value in data.items %}

Creating multiple annotations using a for loop

Here is my code:
phones = Customer.objects.filter(active=True).values('name')\
.annotate(count = Count('phone',filter=Q(phone__model__icontains=model_list[0]))
.annotate(count1 = Count('phone',filter=Q(phone__model__icontains=model_list[1]))
.annotate(count2 = Count('phone',filter=Q(phone__model__icontains=model_list[2]))
.annotate(count3 = Count('phone',filter=Q(phone__model__icontains=model_list[3]))
.annotate(count4 = Count('phone',filter=Q(phone__model__icontains=model_list[4]))
........
html
{% if phones %}
{% for phone in phones %}
<tr>
<td>{{ phone.name }}</td>
<td>{{ phone.count }}</td>
<td>{{ phone.count1 }}</td>
<td>{{ phone.count2 }}</td>
<td>{{ phone.count3 }}</td>
<td>{{ phone.count4 }}</td>
</tr>
{% endfor %}
{% enfif %}
My model_list still has many models. What should I do to simplify these using for loop?
If my model_list has 100 models, this will be very complicated.
I've tried this:
for i in range(len(model_list)):
phone= Customer.objects.filter(active=True).values('name')\
.annotate(count = Count('phone',filter=Q(phone__model__icontains=model_list[i]))
html
{% if phones %}
{% for phone in phones %}
<tr>
<td>{{ phone.name }}</td>
<td>{{ phone.count }}</td>
</tr>
{% endfor %}
{% endif %}
But the result is not what I want, because I only get one of the data.
For example :model_list[0]
Do like this to query for counts:
phones = Customer.objects.filter(active=True).values('name')
for idx, model in enumerate(model_list):
counts = {'count%s' % idx : Count('phone',filter=Q(phone__model__icontains=model)}
phones = phones.annotate(**counts)
Then you would need to pass a range of models to the template (say in models_idx_range as context parameter models_idx_range=range(models_count)) and iterate over counts:
{% if phones %}
{% for phone in phones %}
<tr>
<td>{{ phone.name }}</td>
{% for idx in models_idx_range %}
<td>{{ getattr(phone, 'count%s' % idx) }}</td>
</tr>
{% endfor %}
{% endif %}
I'm not a django expert but i think this is your error:
phone = Customer.objects.filter(active=True).values('name')
for i in range(len(model_list)):
phone= phone.annotate(count = Count('phone',filter=Q(phone__model__icontains=model_list[i]))
You always override your phone with the last value from the for-loop
Try this one
phones = Customer.objects.filter(active=True).values('name')\
.annotate(count = Count('phone',filter=Q(phone__model__icontains=[i for i in model_list]))

How to check if that which is iterated upon is the last key/value in a dict? (probably needs to be done in django template)

The desired outcome is a navigation that look like so:
A | B | C | D | E | ... | X | Y | Z
Note that both A and Z do not have the pipe on the outsides.
This is the template I have currently.
<section id="partners_nav">
<div class="row">
<table align="center" cellpadding="4px">
<tr>
{% for key, value in index.items %}
{% if key in index|last %}
{% if value == None %}
<td>{{ key }}</td>
<td id="partners_nav_bracket">|</td>
{% else %}
<td>{{ key }}</td>
<td id="partners_nav_bracket">|</td>
{% endif %}
{% else %}
{% if value == None %}
<td>{{ key }}</td>
<td id="partners_nav_bracket">|</td>
{% else %}
<td>{{ key }}</td>
<td id="partners_nav_bracket">|</td>
{% endif %}
{% endif %}
{% endfor %}
</tr>
</table>
</div>
The line {% if key in index|last %} is where i'm attempting to check if it is the last item in the iteration.
This does not produce any errors.Yet does not remove the pipe to the right of the letter Z.
Note:
Inside of index is an ordered dictionary which has a key for every letter in the alphabet. And some of these keys have values that are also a letter (the same letter)... This is to use the A | B | C as a jump to navigation at the top of the page. The rest of the keys have a value of None... So the letter still displays at the top of the page but it is not clickable
You might want to check forloop.last template variable. It returns True if it is the last time through the loop:
{% for key, value in index.items %}
...
{% if value %}
<td>{{ key }}</td>
{% else %}
<td>{{ key }}</td>
{% endif %}
{% if not forloop.last %}
<td id="partners_nav_bracket">|</td>
{% endif %}
...
{% endfor %}
You can make use of forloop.first or forloop.last.
<div class="row">
<table align="center" cellpadding="4px">
<tr>
{% for key, value in index.items %}
{% if value == None %}
<td>{{ key }}</td>
{% else %}
<td>{{ key }}</td>
{% endif %}
{% if not forloop.last %}
<td id="partners_nav_bracket">|</td>
{% endif %}
{% endfor %}
</tr>
</table>
</div>
I also cleaned up your markup, because the contents of your if and else were the same.

Jinja if statments

Hopefully someone can help me here..
Lets say I have column a, this column 'a' can have rows of all values. I need to get jinja to look at the data of this row and if it's below a specific value, to change the html (Lets not worry about that)
The below works fine. Both rows of data display as needed.
<table>
{% for row in data %}
<tr>
<td>{{ row['a'] }}</td>
<td>{{ row['b'] }}</td>
</tr>
{% endfor %}
</table>
How can I say for example:
for value in row a, if it's less than 50, do this, else, do this.
UPDATE: Can anyone see an issues with the following?
<table>
{% for row in data %}
<tr>
<td>{{ row['a'] }}</td>
{% if row['b'] <= 10 %}
<td><font color="#FF0000">{{ row['b'] }}</font></td>
{% else %}
<td>{{ row['b'] }}</td>
{% endif %}
<td>{{ row['c'] }}</td>
<td>{{ row['d'] }}</td>
<td>{{ row['e'] }}</td>
</tr>
{% endfor %}
</table>
Implementation of condition would be like this, You need to close the if block in the template.
<table>
{% for row in data %}
<tr>
{% if row['a'] <= 10 %}
<td class="test">{{ row['a'] }}</td>
{% else %}
<td> {{ row['a'] }} </td>
{% endif %}
</tr>
{% endfor %}
</table>

Python-Django: user info in template

I have database, currently from my database its displaying like this in my Template(HTML table) page.
sno--scene--frames--empID
1------001----24-----100
2------002----34-----100
3------003----20-----101
4------004----15-----101
5------005----10-----100
But i want to display like this(below). How to get this from HTML(tables). I am using Python-Django.
sno---scene---frames---empID
1--------001-----24-------100
2--------002-----34-------100
3--------005-----10-------100
------------- tot=68
1------003-----20--------101
2------004-----15--------101
-------------tot=35
You should prepare the data in a view - group them by id, calculate sum. Result cal looks like this:
items_info = [{'items':[item1, item2, item3], 'total': 68}, {'items':[item4, item5], 'total': 35}]
Then template should be like this:
{% for info in items_info %}
{% for item in info.items %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ item.scene }}</td>
<td>{{ item.frames }}</td>
<td>{{ item.id }}</td>
</tr>
{% endfor %}
<tr>
<td colspan="3">TOTAL</td>
<td>{{ info.total }}
</tr>
{% endfor %}
Hope this helps!

Categories

Resources