how to use for loop in html template - django

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.

Related

How to display Model Object Count In Django Admin Index

I am trying to display the count of objects of each model. For this i have edited env > lib > django > contrib > templates > admin > app_list.html, bellow is the code. I am having to doubts here.
I know this is not optimal solution where editing directly in env django folder. So how i can edit the app_list.html so that i can display the count.
I tried {{model}}, but was not able to display count, always come as blank as you can see in image.
Possible out i tried in template html-
{{model}}
Object - {'name': 'Exam categorys', 'object_name': 'ExamCategory', 'perms': {'add': True, 'change': True, 'delete': True, 'view': True}, 'admin_url': '/admin/quiz/examcategory/', 'add_url': '/admin/quiz/examcategory/add/', 'view_only': False}
{{model.count}}
Object -
{{model.all}}
Object -
{{model.objects.all}}
Object -
----------------------------------------------------------------
env > lib > django > contrib > templates > admin > app_list.html
----------------------------------------------------------------
{% load i18n %}
{% if app_list %}
{% for app in app_list %}
<div class="app-{{ app.app_label }} module{% if app.app_url in request.path %} current-app{% endif %}">
<table>
<caption>
{{ app.name }}
</caption>
{% for model in app.models %}
<tr class="model-{{ model.object_name|lower }}{% if model.admin_url in request.path %} current-model{% endif %}">
{% if model.admin_url %}
<th scope="row"><a href="{{ model.admin_url }}"{% if model.admin_url in request.path %} aria-current="page"{% endif %}>{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
<!-- Temporary added this line to get count from model -->
{% if model.add_url %}
<td>Object - {{ model.count }}</td>
{% else %}
<td></td>
{% endif %}
{% if model.add_url %}
<td>{% translate 'Add' %}</td>
{% else %}
<td></td>
{% endif %}
{% if model.admin_url and show_changelinks %}
{% if model.view_only %}
<td>{% translate 'View' %}</td>
{% else %}
<td>{% translate 'Change' %}</td>
{% endif %}
{% elif show_changelinks %}
<td></td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
{% else %}
<p>{% translate 'You don’t have permission to view or edit anything.' %}</p>
{% endif %}

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.

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 %}

How to I get the length or size or number of fields in a form in a django template?

I would like to write a loop like this, so that I can spread the form fields out in a table. :
{% load widget_tweaks %}
{% load mathfilters %}
{% load get_range %}
{% for k in form|length|div:5|floatformat|add:1|get_range %}
<tr>
{% for field in form %}
{% if forloop.counter >= k|mul:5 and forloop.counter <= k|mul:5|add:4 %}
<th>{{ field.label_tag }}{{ field.errors }}</th>
{% endif %}
{% endfor %}
</tr>
<tr>
{% for field in form %}
{% if forloop.counter >= k|mul:5 and forloop.counter <= k|mul:5|add:4 %}
<td>{{ field|add_class:"span4" }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
This doesn't work, but because the code above fails on form|length. In order for this to work, I need to get, in a template, the number of fields in a form. Does anyone know how to do this? I've searched all over but can't find anything. The following do NOT work:
form.len
form.length
form|length
Thanks!
I'm really not sure what you are looking for, but it sounds like this:
{% for field in form %}
<tr>
{% if forloop.counter0|divisibleby:5 %}
<th class="span4">{{ field.label_tag }}{{ field.errors }}</th>
{% else %}
<th>{{ field.label_tag }}{{ field.errors }}</th>
{% endif %}
</tr>
{% endfor%}
{% for field in form %}
<tr>
{% if forloop.counter0|divisibleby:5 %}
<td>{{ field|add_class:"span4" }}</td>
{% else %}
<td>{{ field }}</td>
</tr>
{% endfor %}
I dont like this code, but it was my first idea.
{% for field in form %}
{% if forloop.last %}
{{ forloop.counter }}
{% endif %}
{% enfor %}
form.fields I believe.
{% for field_name in form.fields %}
thanks for your suggestions - they helped! Here is what finally worked for me:
{% for field in form %}
{% if forloop.counter0|divisibleby:5 %}
<tr>
{% for field in form %}
{% if forloop.counter0 >= forloop.parentloop.counter0 and forloop.counter0 <= forloop.parentloop.counter0|add:4 %}
<th>{{ field.label_tag }}{{ field.errors }} </th>
{% endif %}
{% endfor %}
</tr>
<tr>
{% for field in form %}
{% if forloop.counter0 >= forloop.parentloop.counter0 and forloop.counter0 <= forloop.parentloop.counter0|add:4 %}
<td>{{ field }}</td>
{% endif %}
{% endfor %}
</tr>
{% endif %}
{% endfor %}

How to access values for a key in a Django template?

Newbie Question:
I have a dictionary rendering with extra_Context from a method defined in views.py
My views:
extra_context = {
'comment': comment
}
return direct_to_template(request, 'events/comment_detail.html', extra_context)
If i print the comment the it print like this:
[{'comment': u'first', 'user': 2}, {'comment': u'second', 'user': 2}]
I want to pass this dictionary to my template. I tried with this following code:
<tbody>
{% for obj in comment %}
{% for key,val in obj.items %}
<tr class="{% cycle 'odd' 'even' %}">
<td> {{val}}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
It prints :
first
2
second
2
I want in this way:
first 2
second 2
..and so on
What should i add it to get like above ?
Updated!
def comment_detail(request, object_id):
comment_obj = EventComment.objects.filter(event = object_id)
comment = comment_obj.values('comment','user')
extra_context = {
'comment': comment
}
return direct_to_template(request, 'events/comment_detail.html', extra_context)
comment_detail.html
<form action="" method="POST">
<table>
<thead>
<tr><th>{% trans "Comments" %}</th><th>{% trans "Timestamp "%}<th>{% trans "User" %}</th></tr>
</thead>
<tbody>
{% if comments %}
{% for com in comment %}
<td> {{com.comment}}</enter code heretd>
<td> {{com.user}}</td>
{% endfor %}
{% else %}
<td> No comments </td>
{% endif %}
</tr>
</tbody>
</table>
</form>
You don't need that nested for iterating k,v. I just tried this:
View:
def testme(request):
comments = []
comments.append({'user': 2, 'comment': 'cool story bro'})
comments.append({'user': 7, 'comment': 'yep. cool story'})
extra_context = {
'comments': comments
}
return render_to_response('testapp/testme.html', extra_context )
Template:
{% if comments %}
<b>Comments:</b>
<ul>
{% for comment in comments %}
<li>{{ comment.comment }} (id {{ comment.user }})</li>
{% endfor %}
</ul>
{% else %}
<b>No comments</b>
{% endif %}
"for k(k=key), v(v=value) in object.items"
All that is saying is to iterate over every key value pair i.e. such as name = models.CharField(max_length=50) in object.items. Your view has returned context for object.items which each item is a model instance and has a set of k,v pairs associated with it.
Looks like your question just about html markup.
Try this:
<tbody>
{% for obj in comment %}
<tr class="{% cycle 'odd' 'even' %}">
{% for key,val in obj.items %}
<td>{{val}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
or this:
<tbody>
{% for obj in comment %}
<tr class="{% cycle 'odd' 'even' %}"><td>
{% for key,val in obj.items %}
{{val}}<span> </span>
{% endfor %}
</td> </tr>
{% endfor %}
</tbody>