Django template skip line every two iteration - django

I have the following html structure:
<div class="row>
<div class="box"></div>
<div class="box"></div>
</div>
I am using pagination feature on Django to pass on 6 items per page.
How would I go about iterating over the paginator generated object list while wrapper each two box divs with row div?

You can use the forloop.counter in the template
{% for obj in obj_list %}
{% if forloop.counter0|divisibleby:2 %}
<div class="row">
{% endif %}
<div class="box"></div>
<div class="box"></div>
{% if forloop.counter|divisibleby:2 %}
</div>
{% endif %}
{% else %}
Nothing to show
{% endfor %}
and if there are odd number of elements in the list, then it would not have a trailing div. I will let you figure out that scenario by yourself. (it is pretty simple)
Documentation for the forloop.counter0 can be found here
Documentation for divisibleby can be found here

I agree with karthikr's solution, but it doesn't print the </div> if you have 3, 5 items...
You have to add a forloop.last to handle that case:
{% for obj in obj_list %}
{% if forloop.counter0|divisibleby:2 %}
<div class="row">
{% endif %}
<div class="box"></div>
<div class="box"></div>
{% if forloop.counter|divisibleby:2 or forloop.last %}
</div>
{% endif %}
{% else %}
Nothing to show
{% endfor %}

Related

How to switch design for each cards in django templates

How to switch between different card designs for each data in the for loop.
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
These three cards have different designs, Currently facing trouble in switching these cards for each loop in the Django template.
{% for cont in data %}
{% ifequal forloop.counter|divisibleby:"3" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifequal %}
{% ifequal forloop.counter|divisibleby:"2" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifequal %}
{% ifnotequal forloop.counter|divisibleby:"2" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifnotequal %}
{% endfor %}
Third card logic is wrong. I need to change this logic so that for each loop each cards need to be displayed alternatively. And another challenge is that after 3 loop it should close the section, since in a row only 3 cards are allowed.
<section class="section-tours" id="section-tours">
{% ifequal forloop.counter|divisibleby:"3" True %}
{% endifequal %}
{% ifequal forloop.counter|divisibleby:"2" True %}
{% endifequal %}
{% ifequal forloop.counter|divisibleby:"2" True %}
{% endifequal %}
</section>
You can use build in django cycle template tag for this. You can update your html and add the cycle template tag like below to change design of 1st, 2nd and 3rd card.
{% for cont in data %}
<div class="{% cycle 'col-1-of-3' 'col-2-of-3' 'col-3-of-3' %}">
<div class="card">
...
</div>
</div>
{% endfor %}
I hope this will help you :)
Section is closed after printing 3 cards.
<section class='section-tours' id='section-tours'>
<div class="row">
{% for cont in data %}
{% cycle 'tools/col-1-of-3.html' 'tools/col-2-of-3.html' 'tools/col-3-of-3.html' as tmp silent %}
{% include tmp %}
{% cycle "" "" "</div> </section><section class='section-tours' id='section-tours'>" %}
{% endfor %}
</section>
Test the below code and tell me if it helps, since I have not tested it.
I have sliced the for loop for first three values, if you want to repeat the same change the slice for same code.
{% for cont in data|slice:":3" %} #i have sliced it for first three values only
{% if forloop.first %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endif %}
{% ifequal forloop.counter|divisibleby:"2" True %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endifequal %}
{% if forloop.last %}
<div class="col-1-of-3">
<div class="card">
...
</div>
</div>
{% endif %}
{% endfor %}

Getting the last for loop iteration of condition in django templates

I wish to add the class rounded-t-lg shadowon the first iteration inside the if statement, and rounded-b-lg shadow on the last iteration. I have the following code:
{% for note in notes %}
{% if note.is_sticky %}
<div class="flex items-center">
<div class="{% if forloop.first %} rounded-t-lg shadow {% elif forloop.last %} rounded-b-lg shadow {% endif %}">
<!-- code -->
</div>
</div>
</div>
{% endif %}
{% endfor %}
The problem that I'm running into is that forloop.last applies to the last iteration in general, and not the last iteration in the condition. So if I have three objects, where two is sticky, and the last one is not, the class will be applied to the one that is not, since its the last in "line".
How can I apply a class to the last iteration within the is_sticky condition, regardless of the objects that do not meet the condition?
Ideally you should filter the notes list in your view, so it only contains those where is_sticky == True. Depending on your queryset you may just need to add:
.filter(is_sticky=True)
I also think you might need to be careful of the case when there is only 1 element in notes. I guess you want it to be rounded top and bottom, so you need 2 separate if tests, rather than an elsif.
{% for note in notes %}
<div class="flex items-center">
<div class="{% if forloop.first %} rounded-t-lg shadow{% endif %}{% if forloop.last %} rounded-b-lg shadow{% endif %}">
<!-- code -->
</div>
</div>
{% endfor %}
This should work:
{% for note in notes %}
{% if forloop.first %}
{% if note.is_sticky %}
<div class="flex items-center">
<div class="rounded-t-lg shadow">
<!-- code -->
</div>
</div>
</div>
{% endif %}
{% elif forloop.last %}
{% if note.is_sticky %}
<div class="flex items-center">
<div class="rounded-b-lg shadow">
<!-- code -->
</div>
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}

How to pass one django template with a 'for loop' into another one using 'include' statement?

I am working on FAQs page where questions and answers are passed to a template sections based on their categories. I would like to reduce amount of html and use section div as a template
<div id="{{id}}">
<div class="h2">{{category}}</div>
{% for q in faqs %}
{% if q.category == '{{category}}' %}
<ul class="collapsible">
<li>
<div class="collapsible-header">{{q.question}}></div>
<div class="collapsible-body"><span>{{q.answer}}</span></div>
<div class="divider"></div>
</li>
</ul>
{% endif %}
{% endfor %}
</div>
My main html contains following code:
{% with id='m_faq'%}
{% with category='Methodology'%}
{% include 'main/faqs_section.html' %}
{% endwith %}{% endwith %}
I am only able to pass variables id and category.
Is there a way to the for loop as well?
I think the solution would be to create a list for categories in views.py
cat = [ 'Category1', 'Category2', 'Category3','Category4']
pass it to context dictionary and then put additional 'for loop' around section div.
{% for c in cat %}
<div id="">
<div class="h4">{{c}}</div>
{% for q in faqs %}
{% if c == q.category %}
<ul class="collapsible">
<li>
<div class="collapsible-header">{{q.question}}</div>
<div class="collapsible-body"><span>{{q.answer}}</span></div>
<div class="divider"></div>
</li>
</ul>
{% endif %}
{% endfor %}
</div>
{% endfor %}
That will generate a template with list of faqs divided in to sections..

Django template row alternate for multiple content

I've a template design like this
<div class="row">
<div class="col-sm-8"></div>
<div class="col-sm-4"></div>
</div>
<div class="row">
<div class="col-sm-4"></div>
<div class="col-sm-8"></div>
</div>
and I've tried using this article django template rows of multiple items
But output doesnt come as required. How can I do as required.
What I've tried:
{% for item in items %}
<div class="row">
{% if forloop.counter|divisibleby:2 %}
<div class="col-sm-4"></div>
{% else %}
<div class="col-sm-8"></div>
{% endif %}
</div>
{% endfor %}
Your code produce one row per item. If I'm correct, you want 2 items per row.
{% with items_length = items|length%}
<div class="row">
{% for item in items %}
<div class="col-sm-{% cycle '4' '8'%}"></div>
{% if forloop.counter|divisibleby:2 and forloop.counter < items_length %}
</div>
<div class="row">
{% endif %}
{% endfor %}
</div>
{% endwith %}
Something like that should work.
The following is one way to do it:
{% for item in items %}
<div class="row">
{% if forloop.counter0|divisibleby:2 %}
<div class="col-sm-8"></div>
<div class="col-sm-4"></div>
{% else %}
<div class="col-sm-8"></div>
<div class="col-sm-4"></div>
{% endif %}
</div>
{% endfor %}
Notice the use of forloop.counter0.

How do I get odd and even values in a Django for loop template?

I have this code
{% for o in some_list %}
Now I want to do some stuff if I am on an even line. How can I do that?
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#divisibleby
{% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}
In first level cycle:
{% cycle 'odd' 'even' %}
Reference:
Documentation for cycle template tag
<div class="row">
{% for post in posts %}
{% cycle 'odd' 'even' %}
{% if cycle == 'odd' %}
<div class="col-md-6">Odd posts</div>
{% else %}
<div class="col-md-6">Even posts</div>
{% endif %}
{% endfor %}
</div>
OR
<div class="row">
{% for post in posts %}
{% if forloop.counter|divisibleby:2 %}
<div class="col-md-6">Even posts</div>
{% else %}
<div class="col-md-6">Odd posts</div>
{% endif %}
{% endfor %}
</div>
<div class="row">
{% for post in posts %}
{% if loop.index is divisibleby 2 %}
<div class="col-md-6">Even posts</div>
{% else %}
<div class="col-md-6">Odd posts</div>
{% endif %}
{% endfor %}
</div>
http://mitsuhiko.pocoo.org/jinja2docs/html/templates.html#id3