Django fill table column based on subdict key - django

I have a dict in the following format:
{
'P1': {'A': [1,10], 'B': [4,5], 'C': [8,12]},
'P2': {'A': [1,10], 'E': [4,5], 'G': [8,12]},
'P3': {'C': [1,10], 'D': [4,5], 'J': [8,12]}
}
and an HTML table set-up like this:
<table>
<thead>
<tr>
<th></th>
</tr>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
<th>F</th>
<th>G</th>
<th>H</th>
<th>I</th>
<th>J</th>
</tr>
</thead>
.
.
.
what I'm trying to do is outputting the P's letter on the correct "cell", basically the data should go in the correct letter, like this:
Player | A | B | C | D | E | F | G | H | I | J |
P1 | 1 | 4 | 8 | | | | | | | |
P2 | 1 | | | | 4 | | 8 | | | |
P3 | | | 1 | 4 | | | | | | 8 |
I tried this but failed:
{% for k,v in p_dataset.items %}
<tr>
<td>{{k}}</td>
{% for letter, vals in v.items %}
<td>{% if letter == 'A' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'B' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'C' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'D' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'E' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'F' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'G' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'H' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'I' %}{{vals}}{% endif %}</td>
<td>{% if letter == 'J' %}{{vals}}{% endif %}</td>
{% endfor %}
</tr>
{% endfor %}
but all I got where a lot of exceeding tds, how should I do this?
Edit: Thinking about it, perhaps I could add all the subkeys as empty and update them on the view, but is there another way?

Thanks to Chiefir for the idea, I ended up solving it like this:
{% for k,v in p_dataset.items %}
<tr>
<td>{{k}}</td>
<td>{% if v.A %}{{v.A|join:' '}}%{% endif %}</td>
<td>{% if v.B %}{{v.B|join:' '}}%{% endif %}</td>
<td>{% if v.C %}{{v.C|join:' '}}%{% endif %}</td>
<td>{% if v.D %}{{v.D|join:' '}}%{% endif %}</td>
<td>{% if v.E %}{{v.E|join:' '}}%{% endif %}</td>
<td>{% if v.F %}{{v.F|join:' '}}%{% endif %}</td>
<td>{% if v.G %}{{v.G|join:' '}}%{% endif %}</td>
<td>{% if v.H %}{{v.H|join:' '}}%{% endif %}</td>
<td>{% if v.I %}{{v.I|join:' '}}%{% endif %}</td>
<td>{% if v.J %}{{v.J|join:' '}}%{% endif %}</td>
</tr>
{% endfor%}

Related

Jinja change variable value in IF condition

I need to create a table one row and one row
so I wrote following code in template file ;
{% for dict_item in sonuc %}
{% if dict_item.status ==0 %}
{% if count == 1 %}
<tr>
{% set count = 0 %}
{% elif count == 0 %}
<tr class="alt">
{% set count = 1 %}
{% endif %}
<td>{{ dict_item.zaman }}</td><td>{{ dict_item.saat }}</td><td>{{ dict_item.kad }}</td><td>{{ dict_item.mak }}</td><td>{{ dict_item.uyg }}</td> </tr>
{% elif dict_item.status ==1 %}
{% if count == 1 %}
<tr>
{% set count = 0 %}
{% elif count == 0 %}
<tr class="alt">
{% set count = 1 %}
{% endif %}
<td><b>{{ dict_item.zaman }}</b></td><td><b>{{ dict_item.saat }}</b></td><td><b>{{ dict_item.kad }}</b></td><td><b>{{ dict_item.mak }}</b></td><td><font color="red"><b>{{ dict_item.uyg }}</b></font></td> </tr>
{% endif %}
{% endfor %}
but not change count value so all rows created with
<tr class="alt"> tag
as I think I 'm choose the wrong method for solution
I don't understand why I can't change the value of the" content " variable in if condition.
The Jinja2 cycle method is what you're looking for. There's an example in the docs. Note that one of the values in the cycle arguments can be an empty string.

how to use for loop in html template

i try to use for loop in html template to make a table but the probleme he add always column outside the table like in this pic
i dont know why he continue directly out the table(if ther is one object only it's ok but when ther is more than 1 object in the ligne then this happned)
what can i do ?
thanks
html templates
<tr class="col-2">
<th>JOUR</th>
<th>8-10</th>
<th>10-12</th>
<th>12-14</th>
<th>14-16</th>
<th>16-18</th>
</tr>
<tr class="col-2">
<td>SAMEDI</td>
{% for ins in ob %}
{% if ins.jour = 'S' %}
{% if ins.heur = '1' and ins.jour = 'S' %} <td>{{ins}}</td> {% else %} <td> </td> {% endif %}
{% if ins.heur = '2' and ins.jour = 'S' %} <td>{{ins}}</td>{% else %} <td> </td> {% endif %}
{% if ins.heur = '3' and ins.jour = 'S' %} <td>{{ins}}</td>{% else %} <td> </td> {% endif %}
{% if ins.heur = '4' and ins.jour = 'S' %} <td>{{ins}}</td>{% else %} <td> </td> {% endif %}
{% if ins.heur = '5' and ins.jour = 'S' %} <td>{{ins}}</td>{% else %} <td> </td> {% endif %}
{% endif %}
{% endfor %}
{% if a != 2 %}
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
{% endif %}
</tr>
views.py
def tempss(request):
ob=temps.objects.all()
a=1
b=1
c=1
d=1
e=1
f=1
for ins in ob:
if ins.jour=='S':
a=2
elif ins.jour=='D':
b=2
model.py
class temps(models.Model):
JOUR_CHOICES = (
('S', 'Samedi'),
('D', 'Dimanche'),
('L', 'Lundi'),
('M', 'Mardi'),
('R', 'Mercredi'),
('J', 'Jeudi'),
('V', 'Vendredi'),
)
HEUR_CHOICES = (
('1', '8-10'),
('2', '10-12'),
('3', '12-14'),
('4', '14-16'),
('5', '16-18'),
)
jour = models.CharField(max_length=1, choices=JOUR_CHOICES)
heur = models.CharField(max_length=1,choices=HEUR_CHOICES)
salle=models.ForeignKey(salle,on_delete=models.CASCADE)
groupe=models.ForeignKey(groupe,on_delete=models.CASCADE,limit_choices_to={'any_field':False},)
Your loop
{% for ins in ob %}
is going to render an empty table data tag for every object where it does not fulfill the conditions you define.
This part is redundant since you already encapsulate with the same condition:
and ins.jour = 'S' %}
However, the AND makes more sense when you want to create the table (which has a fixed number of rows and cells), and put the conditions into the cells instead - I am sure there is a more elegant solution but given view and model, that's what I came up with:
<td>{% for ins in obj %}{% if ins.jour = 'S' and ins.heur = '1' %}{{ins}}
{% endif %}{% endfor %}</td>
Repeat for the rest of the timeslots accordingly.
Maybe consider constructing the table values in the view instead of the template.

how to show the rank based on a field value in django Templates?

I have a list of details which contain total score. i want to show the rank based on the total score. if the scores are equal the rank must be same. how to do it?
thanks in advance.
{% for rank in ranking %}
{% with forloop.counter as count %}
<tr>
<td>{% if rank.name %} {{rank.name}} {% endif %}</td>
<td>{{count}}</td>
<td>{% if rank.total_score %}{{rank.total_score}}%{% else %} {% trans '0%' %}{% endif %}</td>
</tr>
{% endwith %}
{% endfor %}

First row with two items second one and next with three

I have model (Event) and I want to have template with two ways to display items.
First row have to include two items, with special styling
Second one and next have to include three, with special styling
How can I do this with loop?
you can do like below
views.py
def view(request):
events = Event.objects.all()
l = []
for i in range(0,len(events), 5):
l.append((events[i:i+2], events[i+2:i+5]))
return render(request, "template.html", {"events": l})
template.html
{% for two_items, three_items in events %}
<tr class="class1">
{% for item in two_items %}
<td> {{ item }}</td>
{% endfor %}
<tr>
<tr class="class2">
{% for item in three_items %}
<td> {{ item }}</td>
{% endfor %}
<tr>
{% endfor %}
Combination of cycle and forloop tags will give you desired output:
For example:
{% for item in items %}
{% if forloop.counter < 3 %}
{% if forloop.first %}
<tr class="A">
{% endif %}
<td>{{ item }}</td>
{% endif %}
{% if forloop.counter == 3 %}
</tr>
{% endif %}
{% if forloop.counter >= 3 %}
{% cycle "<tr class='B'>" "" "" %}
<td>{{ item }}</td>
{% cycle "" "" "</tr>" %}
{% endif %}
{% endfor %}

for loop django template logic - how can I do this?

I am trying to output 2 items for each row. I have 4 items coming from db.
<table>
<tr>
{% for item in items %}
<td>
{{item.name}},{{item.size}}
</td>
{% endfor %}
</tr>
</table>
this is giving me
name1, 23m^2 | name2,20m^2 | name3,15m^2 | name4,10m^2
but i need
name1, 23m^2 | name2,20m^2
name3,15m^2 | name4,10m^2
each row being contained in separate <tr>. I am stuck how to break the loop and assign new row..
Just switch the <tr> and forloop, and also use forloop.counter and divisibleby
Something like this:
{% if items %}
<tr>
{% for item in items %}
<td>{{item.name}},{{item.size}}</td>
{% if forloop.counter|divisibleby:2 %}
</tr>
<tr>
{% endif %}
{% endfor %}
</tr>
{% endif %}
You forgot to close <td> tag.
<table>
<tr>
{% for item in items %}
<td>
{{item.name}},{{item.size}}
</td> <!-- here -->
{% endfor %}
</tr>
</table>