Last element in django template list variable - django

I would like to know how to filter out the last element of a list variable from the context object.
{% for d in data %}
{{ d }},
{% endfor %}
I don't want to have the , after the last element. Thank you.
NOTE: This is just a hypothetical example. I know we can use the join filter to achieve the same thing here

Do you mean -
{% for d in data %}
{% if forloop.last %}
{{ d }}
{% else %}
{{ d }},
{% endif %}
{% endfor %}
have a look at the django docs on template for loops

Use {{ data|join:", " }}, it does exactly what you need.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#join

Or you can try this as well -
{% for d in data %}
{{ d }} {% if not forloop.last %},{% endif %}
{% endfor %}
have a look at the docs on template for loops

Related

How can i check if values of models are the same in django loop?

I've a loop:
{% for addimg in post.addimg_set.all %}
<p>
{{ addimg.execution }}<br>
{{ addimg.width }} cm x {{ addimg.height }} cm<br>
{{ addimg.year }}
</p>
{% endfor %}
I want to display some data as long as they are different. If they are equal i want it only to display once like:
{% if addimg.execution == addimg.execution %}
{{ addimg.execution }}<br>
{% endif %}
forgive me my python/django still young.
Any suggestions?
You may find your answer in documentation.
Check this out:
https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#ifchanged
I think you are looking for the {% ifchanged %} template tag.
{% ifchanged addimg.execution %}
{{ addimg.execution }}<br>
{% endifchanged %}

Django loop – remove last comma

I have the following loop set up, but need to remove the comma on the last item (it's to replicate a JSON array for cycle2)
{% for product_in_series in series.get_products %}{%spaceless%}
{% with product_in_series.product as product %}
{%if not forloop.first%}
"<img src='{% version product.get_overview 'page_image' %}'>",
{%endif%}
{% endwith %}
{%endspaceless%}{% endfor %}
Cheers,
R
What about this?
{% for product_in_series in series.get_products %}{%spaceless%}
{% with product_in_series.product as product %}
{%if not forloop.first%}
"<img src='{% version product.get_overview 'page_image' %}'>"
{%if not forloop.last%},{%endif%}
{%endif%}
{% endwith %}
{%endspaceless%}{% endfor %}
{{ forloop.last|yesno:",,"|safe }}
, - is a comma
None of the above works for me.
The correct syntax, as in Django 3.0, is as such
{% with querythisandthat as A %}
{% for u in A %} {{ u.interesting_stuff }}
{% if u == A.last %} . {% else %} ; {% endif %}
{% endfor %}
{% endwith %}
The reason is that A.last is not True/False, but it is the last element of the queryset
https://docs.djangoproject.com/en/3.0/ref/models/querysets/#django.db.models.query.QuerySet.first

Django Templates: how flexible are variables?

I need to have a variable in a teplate that is basically a counter for a for-loop. The problem is: I need to manipulate it, depending on the for-element I am dealing with, I will have to reset the counter (an IF inside the for-loop).
Is this doable inside a Django template?
This is basically what I would like:
{% i = 0 %}
{% for l in list %}
{% if i == 5 %}
{% i = 0 %}
Do Something
<br>
{% else %}
{% i = i + 1 %}
{% endif %}
{% endfor %}
You can't with the builtin tags:
http://www.mail-archive.com/django-users#googlegroups.com/msg27399.html
The following snippets might be a good starting point:
Template counters
Access by index
EDIT: For the record, OP needed a conditional with divisibleby. See the accepted answer here plus the comments in this answer.
What you want is the forloop.counter variable that Django's template language provides.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#for
You would do something like:
{% for element in list %}
{% if forloop.counter > 5 %}
Do something
{% else %}
Do something else
{% endif %}
{% endfor %}
If you want to do something cyclically, you're basically doing a modulo operator (http://en.wikipedia.org/wiki/Modulo_operation), unfortunately, Django Template doesn't quite have this, but it does allow a 'divisible by' operator.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#divisibleby
So you'll add:
{% if {{ forloop.counter|divisibleby:"5" }} %}
{{ whatever }}
{% endif %}

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

How do I check for last loop iteration in Django template?

I have a basic question, in the Django template language how can you tell if you are at the last loop iteration in a for loop?
You would use forloop.last. For example:
<ul>
{% for item in menu_items %}
<li{% if forloop.last %} class='last'{% endif %}>{{ item }}</li>
{% endfor %}
</ul>
{{ forloop.last }}
You can basically use this logic in a for loop:
{% if forloop.last %}
# Do something here
{% endif %}
For example, if you need to put a comma after each item except for the last one, you can use this snippet:
{% for item in item_list %}
{% if forloop.last %}
{{ item }}
{% else %}
{{ item }},
{% endif %}
{% endfor %}
which will become for a list with three items:
first_item, second_item, third_item