how to use Django template if condition inside Django Template? - python

{% if len(verifiedJobs) > 0 %}
{% for v in verifiedJobs %}
companyname:::{{v.companyname}}<br>
jobDescription::::{{v.jobDescription}}<br>
salary:::{{v.salary}}<br>
{% endfor %}
{% endif %}
this is my code and it is not working it is giving errors about my if condition.

Django templates don't understand the length function so that's why its giving you an error.
suppose the length of verifiedjob is 0 it will be considered as false and the if condition will not work and if its value is anything different than 0 it will work
{% if verifiedJobs %}
{% for v in verifiedJobs %}
companyname:::{{v.companyname}}<br>
jobDescription:::{{v.jobDescription}}<br>
salary:::{{v.salary}}<br>
{% endfor %}
{% endif %}

Related

Django Template For Loop - reverese last two iterations

I am using Django 1.10 and Python 3.5.
I have been given some code that consists of a for loop that returns 3 iterations of value in alphabetical order.
For example the for loop returns: Chronological, Combination, Functional.
However I need the for loop to return: Chronological, Functional, Combination (the last two iterations/values are reversed). I am forced to keep the for loop.
Is this at all possible with a for loop?
I have tried combining {% if forloop.last %} with {% if forloop.first%} and also setting the value with {% if forloop.counter == 2 %}...set value to Functional...{% endif %} and {% if forloop.counter == 3 %}...set value to Combination...{% endif %} but I cannot get this to achieve what I want.
Here is my code:
{% for resume_format_image in resume_format_images %}
<div class="col-md-4">
{% with "resumes/resume_format_description_"|add:resume_format_image.style.lower|add:".html" as template_name %}
{% include template_name %}
{% endwith %}
</div>
{% endfor %}
I just figured this out:
{% for resume_format_image in resume_format_images %}
<div class="col-md-4">
{% if forloop.first%}
{% include "resumes/resume_format_description_chronological.html" %}
{% elif forloop.last%}
{% include "resumes/resume_format_description_combination.html" %}
{% else %}
{% include "resumes/resume_format_description_functional.html" %}
{% endif %}
</div>
{% endfor %}
I hope this helps someone.

How can I check that variable is changed in jinja2 template?

I have the list of objects to show on web pages(HTML file).
And the type(graph, table etc.) of objects is different from the situation.
If there is a graph objects, I should load js and css files about a graph.
Because I do not want to load js, css files for graph when there is no graph object in the list,
I have implemented the following jinja2 template HTML file.
{% block body %}
{% set has_graph = 0 %}
{% for item in components %}
{% if item.form == 'graph' %}
{% set has_graph = 1 %}
{% endif %}
{% endfor %}
{% if has_graph == 1 %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
{% endif %}
{% endblock %}
I have found {% set has_graph = 1 %} worked, but the js file was not loaded.
I do not know why {% if has_graph == 1 %} does not work.
I found that the scope of set statement could not be beyond the loop in jinja2 document(http://jinja.pocoo.org/docs/2.9/templates/#id12).
Please keep in mind that it is not possible to set variables inside a block and have them show up outside of it. This also applies to loops. The only exception to that rule are if statements which do not introduce a scope. As a result the following template is not going to do what you might expect:
{% set iterated = false %}
{% for item in seq %}
{{ item }}
{% set iterated = true %}
{% endfor %}
{% if not iterated %} did not iterate {% endif %}
It is not possible with Jinja syntax to do this.
It is true that global variables are generally not within scope inside for loops in jinja, which is a surprise to many (users of Python, Java, etc).
However, the workaround is to declare a dictionary object in that outer scope, which is then available in the for-loop:
{% set foundItem = { 'found': False } %}
{% for item in seq %}
{%- if item.form == "graph" %}
{%- if foundItem.update({'found':True}) %} {%- endif %}
{%- endif %}
{% endfor %}
{% if not iterated %} did not iterate {% endif %}
{% if foundItem.flag %} pull in graph CSS/JS {% endif %}

Switch Case in Django Template

I'm trying to put different template for different category based on category ID. I'm using Django 1.3. Switch case is not working with Django 1.3, I get this error:
Invalid block tag: 'switch', expected 'endblock' or 'endblock content'
but switch case had been correctly closed.
Here is my code:
{% switch property.category.id %}
{% case 0 %}
<h4>'agriculture'</h4>
{% case 1 %}
<h4>'Residential'</h4>
{% case 2 %}
<h4>'commiercial'</h4>
{% case 3 %}
<h4>'mixed use'</h4>
{% case 4 %}
<h4>'Industrial'</h4>
{% else %}
<h4>'retail'</h4>
{% endswitch %}
What is the error in this code?
There is no {% switch %} tag in Django template language. To solve your problem you can
either use this Django snippet, that adds the functionality,
or re-write your code to a series of {% if %}s.
The second option in code:
{% if property.category.id == 0 %}
<h4>'agriculture'</h4>
{% elif property.category.id == 1 %}
<h4>'Residential'</h4>
{% elif property.category.id == 2 %}
<h4>'commiercial'</h4>
{% elif property.category.id == 3 %}
<h4>'mixed use'</h4>
{% elif property.category.id == 4 %}
<h4>'Industrial'</h4>
{% else %}
<h4>'retail'</h4>
{% endif %}
As Alasdair correctly mentioned in his comment, the {% elif %} tag was introduced in Django 1.4. To use the above code in an older version you need to upgrade your Django version or you can use a modified version:
{% if property.category.id == 0 %}
<h4>'agriculture'</h4>
{% endif %}
{% if property.category.id == 1 %}
<h4>'Residential'</h4>
{% endif %}
{% if property.category.id == 2 %}
<h4>'commiercial'</h4>
{% endif %}
{% if property.category.id == 3 %}
<h4>'mixed use'</h4>
{% endif %}
{% if property.category.id == 4 %}
<h4>'Industrial'</h4>
{% endif %}
{% if property.category.id < 0 or property.category.id > 4 %}
<h4>'retail'</h4>
{% endif %}
This modification is safe** (but inefficient) here since the ID can't be equal to two different integers at the same time.
** as long as you only use integers for the IDs which is probable
However I would strongly recommend upgrading to a newer Django version. Not only because of the missing {% elif %} tag but mainly for security reasons.

How can I concatenate forloop.counter to a string in my django template

I am already trying to concatenate like this:
{% for choice in choice_dict %}
{% if choice =='2' %}
{% with "mod"|add:forloop.counter|add:".html" as template %}
{% include template %}
{% endwith %}
{% endif %}
{% endfor %}
but for some reason I am only getting "mod.html" and not the forloop.counter number. Does anyone have any idea what is going on and what I can do to fix this issue? Thanks alot!
Your problem is that the forloop.counter is an integer and you are using the add template filter which will behave properly if you pass it all strings or all integers, but not a mix.
One way to work around this is:
{% for x in some_list %}
{% with y=forloop.counter|stringformat:"s" %}
{% with template="mod"|add:y|add:".html" %}
<p>{{ template }}</p>
{% endwith %}
{% endwith %}
{% endfor %}
which results in:
<p>mod1.html</p>
<p>mod2.html</p>
<p>mod3.html</p>
<p>mod4.html</p>
<p>mod5.html</p>
<p>mod6.html</p>
...
The second with tag is required because stringformat tag is implemented with an automatically prepended %. To get around this you can create a custom filter. I use something similar to this:
http://djangosnippets.org/snippets/393/
save the snipped as some_app/templatetags/some_name.py
from django import template
register = template.Library()
def format(value, arg):
"""
Alters default filter "stringformat" to not add the % at the front,
so the variable can be placed anywhere in the string.
"""
try:
if value:
return (unicode(arg)) % value
else:
return u''
except (ValueError, TypeError):
return u''
register.filter('format', format)
in template:
{% load some_name.py %}
{% for x in some_list %}
{% with template=forloop.counter|format:"mod%s.html" %}
<p>{{ template }}</p>
{% endwith %}
{% endfor %}
You probably don't want to do this in your templates, this seems more like a views job: (use of if within a for loop).
chosen_templates=[]
for choice in choice_dict:
if choice =='2':
{% with "mod"|add:forloop.counter|add:".html" as template %}
template_name = "mod%i.html" %index
chosen_templates.append(template_name)
Then pass chosen_templates to your template where you will have only
{% for template in chosen_templates %}
{% load template %}
{% endfor %}
Also, I don't quite understand why you are using a dict to select the template with a number that is not in the dictionnary. for key,value in dict.items() may be what you are looking for.
Try without using the block "with"
{% for choice in choice_dict %}
{% if choice =='2' %}
{% include "mod"|add:forloop.counter|add:".html" %}
{% endif %}
{% endfor %}

How can I use break and continue in Django templates?

I want to put break and continue in my code, but it doesn't work in Django template. How can I use continue and break using Django template for loop. Here is an example:
{% for i in i_range %}
{% for frequency in patient_meds.frequency %}
{% ifequal frequency i %}
<td class="nopad"><input type="checkbox" name="frequency-1" value="{{ i }}" checked/> {{ i }} AM</td>
{{ forloop.parentloop|continue }} ////// It doesn't work
{ continue } ////// It also doesn't work
{% endifequal %}
{% endfor%}
<td class="nopad"><input type="checkbox" name="frequency-1" value="{{ i }}"/> {{ i }} AM</td>
{% endfor %}
Django doesn't support it naturally.
You can implement forloop|continue and forloop|break with custom filters.
http://djangosnippets.org/snippets/2093/
For-loops in Django templates are different from plain Python for-loops, so continue and break will not work in them. See for yourself in the Django docs, there are no break or continue template tags. Given the overall position of Keep-It-Simple-Stupid in Django template syntax, you will probably have to find another way to accomplish what you need.
For most of cases there is no need for custom templatetags, it's easy:
continue:
{% for each in iterable %}
{% if conditions_for_continue %}
<!-- continue -->
{% else %}
... code ..
{% endif %}
{% endfor %}
break use the same idea, but with the wider scope:
{% set stop_loop="" %}
{% for each in iterable %}
{% if stop_loop %}{% else %}
... code ..
under some condition {% set stop_loop="true" %}
... code ..
{% endif %}
{% endfor %}
if you accept iterating more than needed.
If you want a continue/break after certain conditions, I use the following Simple Tag as follows with "Vanilla" Django 3.2.5:
#register.simple_tag
def define(val=None):
return val
Then you can use it as any variable in the template
{% define True as continue %}
{% for u in queryset %}
{% if continue %}
{% if u.status.description == 'Passed' %}
<td>Passed</td>
{% define False as continue %}
{% endif %}
{% endif %}
{% endfor %}
Extremely useful for any type of variable you want to re-use on template without using with statements.

Categories

Resources