Django template: condition check with previous object - django

I need check the condition with previous object in loop.
(previous_object) is for illustration only.
{% for object in objects %}
{% if (previous_object).clicks == 0 %} #this reference must be based on the loop's previous object.
<button type="submit"> OK </button>
{% endif %}
{% endfor %}
Does anyone have any ideas?
Thanks!

You might be interested in using {% ifchanged %} filter. This condition is true only when a feature of an item is different from previous item in the list.
{% for item in items %}
{% ifchanged item.clicks %}
<button type="submit"> OK </button>
{% endifchanged %}
{% endfor %}

Related

Add html code if the element is first in query - Django

In the Bootstrap slider, the first element has the value "active", how to check and add this value to the html code for the queryset, if element is first.
Example (which is not working):
{% for obj in query %}
<div class="carousel-item {% if query|first %}active{% endif %}">
[...]
</div>
{% endfor %}
*this gives activity for all items, not just the first. Expected result is only for first.
You can work with forloop.first [Django-doc] to check if it is the first element, so:
{% for obj in query %}
<div class="carousel-item{% if forloop.first %} active{% endif %}">
[...]
</div>
{% endfor %}
The forloop.first will return:
True if this is the first time through the loop
You can use forloop.counter like this:
{% for obj in query %}
<div class="carousel-item {% if forloop.counter == 1 %} active {% endif %}">
[...]
</div>
{% endfor %}
forloop.counter is 1 index based counter used to store current index of the loop.

How to iterate over a queryset in django template?

I am aware that this is very likely a duplicate but solutions provided in alike questions did not help.
This is at first glance very straightforward issue, it should work by all means but for some reason, it does not.
In a Django template, I am filtering a queryset of records based on the current user. Then I loop through it and want to display each result separately. Nothing complicated. The code goes:
{% if user.is_authenticated %}
{% if user.quick_links.all %}
{{ user.quick_links.all }}
<h2>Moje rychlé přístupy:</h2>
{% for link in user.quick_liks.all %}
<div class="col-md-2">
<button class="btn btn-info">{{ link.link_name }</button>
</div>
{% endfor %}
{% endif %}
{% endif %}
the {{ user.quick_links.all }} displays
<QuerySet [<UserQuickAccessLink: Link uživatele david#email.eu: Google>, <UserQuickAccessLink: Link uživatele david#email.eu: Coding Music>]>
but then the program never enters the for loop even though the iterable is clearly there.
{% for link in user.quick_liks.all %}
<div class="col-md-2">
<button class="btn btn-info">{{ link.link_name }} </button>
</div>
{% endfor %}
The above is never executed.
What is the trick here?
If that is your actual code, in your for loop you have a typo;
It's supposed to be
{% for link in user.quick_links.all %}
and not
{% for link in user.quick_liks.all %}

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

If statement in my Django template...Is there a better way?

In my Django template: I'm trying to add an extra div around my for loop only if the length of the data being passed to the template is 3. This is what I'm trying right now but it seems like there could be better way than doing two if statements to check for the length:
{% if items|length == 3 %}
<div class='three-item-wrap'>
{% endif %}
{% for item in items %}
.......
{% endfor %}
{% if items|length == 3 %}
</div> //close .three-item-wrap
{% endif %}
you can try like that
{% if items|length == 3 %}
<div class='three-item-wrap'>
{% for item in items %}
.......
{% endfor %}
</div>
{% else %}
#another logic goes here
{% endif %}
if you want know more refer the docs django if tempalate
I think better way would be to make single if statement check. Just like this:
{% if items|length == 3 %}
<div class='three-item-wrap'>
{% for item in items %}
.......
{% endfor %}
</div>
{% else %}
{% for item in items %}
.......
{% endfor %}
{% endif %}
This way is better because of Django render engine, which firstly check if statements and then do for loop.
And if something crash in your code, div will be without closing tag </div>. Instead in my code there is no option for div to be without closing tag.

Django simple pagination in detail view between items

I want to add simple back/next pagination in my item detail view.
How can I do that ?
I have something like that in my template:
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
Back
{% endif %}
{% if page_obj.has_next %}
Next: {{ item.title }}
{% endif %}
</span>
</div>
{% endif %}
The main thing is that I want to do this in ItemDetailView, not in ItemListView, because in list view I have all items, and I just want to go between items in detail view.
Thanks a lot for help.