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

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.

Related

in django template unable to show content inside if block

when i write if statement nothing show in html but when i remove the if statement the code show all items what is wrong
{% for catagory in catagory_list %}
{% for item in product_list %}
{% if item.catagory == "Fruits" %}
<p>{{item.catagory}}</p>
<p>{{item.name}}</p>
<p>{{item.price}}</p>
<img src="{{item.image.url}}" alt="">
{% endif %}
{% endfor %}
{% endfor %}
Because catagory is an Object, Try:
{% if item.catagory.name == "Fruits" %}
assuming that catagory model has an attribute "name"

Django list in template without trailing comma in a nested for loop

I am trying to create a list of items in a Django template that are separated by commas, but with no comma after the last item. The list of items comes through a for loop within a for loop. I tried to do something like this.
{% for thing in things %}
{% spaceless %}
{% for o in thing.otherthing_set.all %}
<span>{{ o.name }}: </span>
{% if o.attribute == 'this' %}
<span>{{ o.otherattribute}}</span>
{% if not forloop.last %}
<span>, </span>
{% endif %}
{% endif %}
{% endfor %}
{% endspaceless %}
<br>
{% endfor %}
But sometimes there is an extra comma because sometimes for the last item cycled through o.attribute == 'this' isn't always true.
What I would like to do is somehow have
{% for o in thing.otherthing_set.all %}
be filtered for just for o.attribute == 'this' before even going through the for loop, but it doesn't seem that this is possible.
Any suggestions?

The best way to divide card-deck into rows in django template

What I have(image)
So i need to divide these cards into 4-5 cards per row.
My solution is simple
<div class="card-deck">
{% for book in books %}
{% include 'books/book_element.html' %}
{% endfor %}
</div>
And I have tried for a while and was doing some brainstorm
{% for book in books %}
{% if forloop.counter|divisibleby:"5" or forloop.counter == 1 %}
<div class="card-deck">
</div>
{% endif %}
{% endfor %}
How can I include a template into a div.card-deck?
You need to close the previous row and open a new one in your loop. Something like this:
<div class="card-deck">
{% for book in books %}
{% include 'books/book_element.html' %}
{% if forloop.counter|divisibleby:"5" %}
{# Close the current deck and start a new one %}
</div><div class="card-deck">
{% endif %}
{% endfor %}
</div><!-- The final deck is closed here, outside the loop -->

Django template: check for empty query set

Is there a way to check for an empty query set in the Django template? In the example below, I only want the NOTES header to be displayed if there are notes.
If I put an {% empty %} inside the "for" then it does display whatever is inside the empty tag, so it knows it's empty.
I'm hoping for something that does not involve running the query twice.
{% if notes - want something here that works %}
NOTES:
{% for note in notes %}
{{note.text}}
{% endfor %}
{% endif %}
Clarification: the above example "if notes" does not work - it still displays the header even with an empty query set.
Here's a simplified version of the view
sql = "select * from app_notes, app_trips where"
notes = trip_notes.objects.raw(sql,(user_id,))
return render_to_response(template, {"notes":notes},context_instance=RequestContext(request))
Edit: the view select selects from multiple tables.
Have a look at the {% empty %} tag.
Example from the documentation
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% empty %}
<li>Sorry, no athletes in this list.</li>
{% endfor %}
</ul>
Link: https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#for-empty
If you are interested in a table, or some kind of heading if there are results, add the forloop.first:
{% for athlete in athlete_list %}
{% if forloop.first %}
Athlete Name:
{% endif %}
{{ athlete.name }}
{% empty %}
Sorry, no athletes in this list.
{% endfor %}
Try {% if notes.all %}. It works for me.
In your view check whether notes is empty or not. If it is then you pass None instead:
{"notes": None}
In your template you use {% if notes %} as normal.
It's unfortunate that you're stuck using a raw query set - they're missing a lot of useful behavior.
You could convert the raw query set into a list in the view:
notes_as_list = list(notes)
return render_to_response(template, {"notes":notes_as_list},context_instance=RequestContext(request))
Then check it as a boolean in the template:
{% if notes %}
Header
{% for note in notes %}
{{ note.text }}
{% endfor %}
{% endif %}
You could also make it happen without conversions using forloop.first:
{% for note in notes %}
{% if forloop.first %}
Header
{% endif %}
{{ note.text }}
{% endfor %}
What about:
{% if notes != None %}
{% if notes %}
NOTES:
{% for note in notes %}
{{ note.text }}
{% endfor %}
{% endif %}
{% else %}
NO NOTES AT ALL
{% endif %}
Your original solution
{% if notes %}
Header
{% for note in notes %}
{{ note.text }}
{% endfor %}
{% endif %}
Works now with Django 1.7 and thanks to QuerySet caching, it does not cost and extra query.
Often the right way to do this is to use the {% with ... %} tag. This caches the query so it runs only once and also gives you more flexibility with your markup than using {% empty %}.
{% with notes as my_notes %}
{% if my_notes %}
<ul>
{% for note in my_notes %}
<li>{{ note }}</li>
{% endfor %}
</ul>
{% else %}
<p>Sorry, no notes available</p>
{% endif %}
{% endwith %}
With this particular example I'm not sure how useful it is but if you're querying Many-to-Many field, for instance, it's likely what you want to do.
Use {% empty %} in django templates
{% if list_data %}
{% for data in list_data %}
{{ data.field_1 }}
{% endfor %}
{% else %}
<p>No data found!</p>
{% endif %}
We can write above code with {% empty %}.
{% for data in list_data %}
{{ data.field_1 }}
{% empty %}
<p>No data found!</p>
{% endfor %}

Skip particular step in forloop Django

HI i am using a forloop in django template
{% for image in images %}
{% endfor %}
which executes for 10 steps
but i want to skip the 5th step and execute for remaining
how can i do this please suggest ...
{% for image in images %}
{% if forloop.counter != 5 %}
...
{% endif %}
{% endfor %}
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#for
{% for image in images %}
{% if forloop.counter0 != 5 %}
...
{% endif %}
{% endfor %}
this works for me