Django Template loop with variable - django

I am having issue with django html variable so I made the below code which is working .
{%for field in instance %}
<tr>
<td width="250">
{{ field.Item }}
</td>
<td>
<input type="text" value={{ field.P_640 }} >
</td>
{% endfor %}
But at the view section I have variables and sometimes I am pushing filter value. P_640 and sometimes P_630 .How can I make my template to look to the colomn 1 instead of looking the field name like {{ field.P_640 }} , because it's not working when I push P_630. ?

This is how you would do it:
{% for field in instance %}
<tr>
<td width="250">
{{ field.Item }}
</td>
<td>
<input type="text" value="
{% if field.P_640 }}
{{ field.P_640 }}
{% elif field.P_630 %}
{{ field.P_630 }}
{% endif %}
">
</td>
</tr>
{% endfor %}
Check for every value that could exist and then output it.
If there are multiple values, replace {% elif %} with {% endif %} {% if %};

Related

How to loop through crispy fields

How can I arrange my form in a table?
I had a normal form and I was arranging it in my template like this.
<table border="0" >
{% for field in form %}
<tr >
<td>
<label for="{{ field.label }}">{{ field.label_tag }}
{% if field.field.required %}<span style="color:red"; class="special_class">*</span>{% endif %}</label>
</td>
<td>
{{ field }}
</td>
</tr>
{% endfor %}
</table>
Now I want to use crispy forms. but couldn't figure out how to display my form.
of cause it has works with this.
{% load crispy_forms_tags %}
{% crispy form %}
but that was not arranging my fields well,
how can I access these fields by a loop?
Any help would be greatly appreciated.
You can iterate over fields and then use crispy like this:
{% for field in form %}
{{ field|as_crispy_field }}
{% endfor %}

Displaying Unescaped in Django Template

I have a form with a title and body but for certain cases the title should be autofilled to a value from the page:
To solve this I used a hidden input type:
<form action="" method="POST"> {% csrf_token %}
<table>
<tr>
<td>
<b>Title: </b>
</td>
{% url 'forum:new_topic' forum.pk as the_url %}
{% ifequal request.path the_url %}
<td>
{{ modelform.title}}
</td>
{% else %}
<td>
{% autoescape off %}
<input type="hidden" value="{{ modelform.title}}" >
{% endautoescape %}
Re:{{ thread.title }}
</td>
{% endifequal %}
</tr>
<tr>
<td>
<b>Body: </b>
</td>
<td>
{{ modelform.body}}
</td>
</tr>
</table>
<input type="submit" value="Submit" />
</form>
However the way it displays on the page is "> Re: .... and is for some reason not escaping the ending quote and >. I tried single quotes but that prevents submission.
Not sure what direction I should go in.

how to iterate over a list of variable length in django template?

I have a list of values like:
list_of_values = ['clients':['add, view'], 'vendors': ['add', 'delete', 'change'], 'companies': ['add', 'view', 'delete', 'change']]
Using django template tags I have to make a template like:
Activities ADD | VIEW | CHANGE | DELETE
clients checkbox checkbox checkbox checkbox
vendors checkbox checkbox checkbox checkbox
companies checkbox checkbox checkbox checkbox
Kindly let me know how can I achieve this?
List of values looks more like a dictionary to me, assuming it is:
<table>
<tr>
<th>Activities</th>
<th>ADD</th>
<th>VIEW</th>
<th>CHANGE</th>
<th>DELETE</th>
</tr>
{% for key in list_of_values %}
<tr>
<td>{{ key }}</td>
<td>
{% if 'add' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
<td>
{% if 'view' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
<td>
{% if 'change' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
<td>
{% if 'delete' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
</tr>
{% endfor %}
</table>

Django - iterate number in for loop of a template

I have the following for loop in my django template displaying days. I wonder, whether it's possible to iterate a number (in the below case i) in a loop. Or do I have to store it in the database and then query it in form of days.day_number?
{% for days in days_list %}
<h2># Day {{ i }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
Django provides it. You can use either:
{{ forloop.counter }} index starts at 1.
{{ forloop.counter0 }} index starts at 0.
In template, you can do:
{% for item in item_list %}
{{ forloop.counter }} # starting index 1
{{ forloop.counter0 }} # starting index 0
# do your stuff
{% endfor %}
More info at: for | Built-in template tags and filters | Django documentation
Also one can use this:
{% if forloop.first %}
or
{% if forloop.last %}
{% for days in days_list %}
<h2># Day {{ forloop.counter }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
or if you want to start from 0
{% for days in days_list %}
<h2># Day {{ forloop.counter0 }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
from the docs https://docs.djangoproject.com/en/stable/ref/templates/builtins/#for
you can found it to count items you can use a counter like this
{% for job in jobs %}
<td>{{ forloop.counter }}</td>
<td>{{ job.title }}</td>
<td>{{ job.job_url }}</td>
{% endfor %}
{{ forloop.counter }} start counting from 1
{{ forloop.counter0 }} start counting from 0
Do like this,
{% for days in days_list %}
<h2># Day {{ forloop.counter }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
[Django HTML template doesn't support index as of now], but you can achieve the goal:
If you use Dictionary inside Dictionary in views.py then iteration is possible using key as index. example:
{% for key, value in DictionartResult.items %} <!-- dictionartResult is a dictionary having key value pair-->
<tr align="center">
<td bgcolor="Blue"><a href={{value.ProjectName}}><b>{{value.ProjectName}}</b></a></td>
<td> {{ value.atIndex0 }} </td> <!-- atIndex0 is a key which will have its value , you can treat this key as index to resolve-->
<td> {{ value.atIndex4 }} </td>
<td> {{ value.atIndex2 }} </td>
</tr>
{% endfor %}
Elseif you use List inside dictionary then not only first and last iteration can be controlled, but all index can be controlled. example:
{% for key, value in DictionaryResult.items %}
<tr align="center">
{% for project_data in value %}
{% if forloop.counter <= 13 %} <!-- Here you can control the iteration-->
{% if forloop.first %}
<td bgcolor="Blue"><a href={{project_data}}><b> {{ project_data }} </b></a></td> <!-- it will always refer to project_data[0]-->
{% else %}
<td> {{ project_data }} </td> <!-- it will refer to all items in project_data[] except at index [0]-->
{% endif %}
{% endif %}
{% endfor %}
</tr>
{% endfor %}
End If ;)
//
Hope have covered the solution with Dictionary, List, HTML template, For Loop, Inner loop, If Else.
Django HTML Documentaion for more methods: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/
I think you could call the id, like this
{% for days in days_list %}
<h2># Day {{ days.id }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}

Django/Python: Loop over selected form fields in Django template

I have a form with n fields. The first 4 fields should be displayed differently in my template then the rest of the form. Therefore, I was wondering if I can somehow loop over the first 4 fields, end the loop and continue looping over the rest of the fields later in the template.
<table>
{% for field in form %}
{% if forloop.counter == 4 <<< Break here >>>%}
<tr>
<td> {{ field.label_tag }} </td>
<td> {{ field }} </td>
</tr>
{% endfor %}
</table>
.... Different code ....
<table>
{% for field in form %} <<< Continue here >>>
<tr>
<td> {{ field.label_tag }} </td>
<td> {{ field }} </td>
</tr>
{% endfor %}
</table>
I have found this code but I was wondering if I could structure the template differently or if I have missed some new changes in Django 1.3 which allow the breaking of loops now.
Normally, I would split the form in two seperate forms, but I would like to reuse the form definition in other templates as well, therefore I would like to keep all information together in one form.
Thank you for your advice!
It's the same solution as other "can't do it in the template" problems: do it in the view. I truly believe added complexity and further separation of logic into multiple code areas (tags, new files, etc.) only hurts maintainability. I separate / implement DRY only when things actually do get repetitive, unreadable, etc.
Everything else is premature optimization.
Django won't know the difference when a form is submitted.
fields = list(form)
part1, part2 = fields[:4], fields[4:]
{% for field in part1 %}{{ field }}{% endfor %}
...
{% for field in part2 %}{{ field }}{% endfor %}
I would suggest you write your own custom template. Perhaps your filter could look like this:
def show_part(form,section=1):
display = ''
for id,field in enumerate(form):
if int(section) == 1 and id > 3:
break
elif int(section) == 2 and id < 3:
continue
display += '<tr><td>'+field.label_tag+'</td>'
display += '<td>'+field+'</td></tr>'
return display
and use the following in your template:
<table>
{{ form|show_part:"1" }}
</table>
<table>
{{ form|show_part:"2" }}
</table>
Since form is a list, you could also use Django's built-in slice template filter: https://docs.djangoproject.com/en/1.3/ref/templates/builtins/#slice
Your example would become:
<table>
{% for field in form|slice:":4" %}
<tr>
<td> {{ field.label_tag }} </td>
<td> {{ field }} </td>
</tr>
{% endfor %}
</table>
.... Different code ....
<table>
{% for field in form|slice:"4:" %}
<tr>
<td> {{ field.label_tag }} </td>
<td> {{ field }} </td>
</tr>
{% endfor %}
</table>
You're almost there, if you just add
<table>
{% if forloop.counter <= 4 %}
... first four fields
{% else %}
... other fields
{% endif %}
If you need two different tables you could add:
{% if forloop.counter == 1 %}
<table>
{% endif %}
{% if forloop.last %}
</table>
{% endif %}
That's not a very pretty solution, but it works. You could also consider using two forms.
Shorter than "Yuji 'Tomita' Tomita" answer
Make list for form on your view:
context = {'form': list(form)}
return render(request, template, context)
and get each field on template by |slice
{% for field in form|slice:":4" %}
<tr>
<td> {{ field.label_tag }} </td>
<td> {{ field }} </td>
</tr>
{% endfor %}