Jinja2 setting and using variables - flask

I have the following
<thead>
<tr>
<th>Name</th>
{% if datas|length > 0 %}
{% set longest = [] %}
{% for data in datas %}
{% if data['numbers']|length > longest|length %}
{% set longest = data['numbers'] %}
{% endif %}
{% endfor %}
{% for i in longest %}
<th></th>
{% endfor %}
{% endif %}
</tr>
</thead>
I am trying to make enough headers to accommodate the longest list of numbers in the datas dictionary.
Can anyone see what I am doing wrong?
Chris

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

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

Custom formset templates in Django

I am using a Django formset for this model:
class Book(models.Model):
book_id=models.AutoField(primary_key=True,unique=True)
book_name=models.CharField(max_length=30)
publisher_name=models.CharField(max_length=40)
author=models.ForeignKey(Author)
The formset is defined thus:
BookFormset = inlineformset_factory(Author, Book,
fields=('book_id','book_name', 'publisher_name'), extra=1,
can_delete=False)
The template is:
{{ formset.non_form_errors.as_ul }}
<table id="formset" class="form">
{% for form in formset.forms %}
{% if forloop.first %}
<thead><tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}
{% endfor %}
</tr></thead>
{% endif %}
<tr class="{% cycle row1,row2 %}">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
The fields are displayed column-wise, but I would like them to be displayed row-wise.
The above code produces output like this:
Book name Publisher name
book_field Publisher_field
I would like the output to look like this:
Book name book_field
Publisher name Publisher_field
How can I do this?
In your template, you have two <tr> elements, each of which contains a loop over form.visible_fields, each iteration of which generates a single <th> or <td>.
Change this round so that you have a single loop over form.visible_fields, each iteration of which contains a single <tr> element containing a <th> and a <td>. Like this:
<table id="formset" class="form">
{% for form in formset.forms %}
{% for field in form.visible_fields %}
<tr class="{% cycle row1,row2 %}">
<th>{{ field.label|capfirst }}</th>
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
</tr>
{% endfor %}
{% endfor %}
</table>
The examples above seem to show a column-wise layout, which appears to be the default layout when a formset renders itself.
To make it row-wise, use something like this:
<table>
{% for form in formset.forms %}
{% if forloop.first %}
<thead>
{% for field in form.visible_fields %}
<th>{{ field.label }}</th>
{% endfor %}
</thead>
<tbody>
{% endif %}
<tr class="{% cycle row1,row2 %}">
{% for field in form.visible_fields %}
<td>
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% if forloop.last %}
</tbody>
{% endif %}
{% endfor %}
</table>

Is this a bug in django template re: forloop.parentloop.first or do I misunderstand?

from django.template import Template, Context
template = Template("""
{% for language in languages %}
THIS IS forloop.parentloop.first +++++++++
{% for tag in revision_tags %}
{% for case in CASES %}
<tr>
{% if forloop.parentloop.first %}<th rowspan="6">{{ language|capfirst }}</th>{% endif %}
{% if forloop.first %}<th rowspan="2">{{ tag }}</th>{% endif %}
<th>{{ case|capfirst }}</th>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
""")
c = Context({
'languages': ["english", "french"],
'revision_tags': ["d", "s", "p"],
'CASES': ["foo", "bar"],
})
h = template.render(c)
print h
I expect to see each language only once but I get them twice.
Try this(not tested)...
{% for language in languages %}
THIS IS forloop.parentloop.first +++++++++
{% for tag in revision_tags %}
{% if forloop.parentloop.first %}<th rowspan="6">{{ language|capfirst }}</th>{% endif %}
{% for case in CASES %}
<tr>
{% if forloop.first %}<th rowspan="2">{{ tag }}</th>{% endif %}
<th>{{ case|capfirst }}</th>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
This is not a bug, I misunderstood. The test should be {% if forloop.parentloop.first and forloop.first %} to get 1 true per grand parent iteration, language in this case.
{% for language in languages %}
{% for tag in revision_tags %}
{% for case in CASES %}
<tr>
{% if forloop.parentloop.first and forloop.first %}
<th rowspan="6">{{ language|capfirst }}</th>
{% endif %}
{% if forloop.first %}<th rowspan="2">{{ tag }}</th>{% endif %}
<th>{{ case|capfirst }}</th>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}