Sum a value inside a loop in jinja - templates

I have a for loop in a jinja template:
<ul>
{%- for t in tree recursive %}
<li><span class="li_wrap">
<span><i class="glyphicon {{ 'glyphicon-folder-close' if t.type == 'folder' else 'glyphicon-file'}}"></i> {{ t.name }}</span>
{% if t.type != 'folder' %}
<span class="pull-right">Size: {{ t.size/1000 }} kb </span>
{% endif %}
</span>
{%- if t.children -%}
<ul>{{ loop(t.children) }}</ul>
{%- endif %}
</li>
{%- endfor %}
</ul>
what I want is to sum the value of t.size and use it as a total size number, but above this block.
What is the best way to do that?

You must use the jinja function SUM => http://jinja.pocoo.org/docs/
This code should work
Total: {{ t|sum(attribute='size') }}

Related

Listing Tags of a Post in Django CMS and Aldryn NewsBlog

I am trying to figure out how to display tags belonging to an article created within Aldryn NewsBlog plugin. Unfortunately, I cannot find any documentation on how do it.
I was able to display categories using the following code.
<span style="margin: 0; display: block">
<h4 style="display:inline-flex">Categories:</h4>
{% for category in article.categories.all %}
{{ category.name }} {% if not forloop.last %}, {% endif %}
{% endfor %}
</span>
For tags, I am using this code:
<span style="margin: 0; padding-bottom: 0; display: block">
<h4 style="display:inline-flex">Tags:</h4>
{% for tag in article.tag %}
{{ tag.name }} {% if not forloop.last %}, {% endif %}
{% endfor %}
</span>
What am I doing wrong? Could anyone tell me how to display tags?
this is the official tags template of aldryn-newsblog, it worked for me:
{% load i18n apphooks_config_tags %}
<div class="aldryn aldryn-newsblog aldryn-newsblog-tags">
<ul class="list-unstyled">
<li{% if not newsblog_tag %} class="active"{% endif %}>
{% trans "All" %}
</li>
{% for tag in tags %}
<li{% if newsblog_tag.id == tag.id %} class="active"{% endif %}>
<a href="{% namespace_url "article-list-by-tag" tag.slug namespace=instance.app_config.namespace default='' %}">
{{ tag.name }}
<span class="badge">{{ tag.article_count }}</span>
</a>
</li>
{% endfor %}
</ul>
https://github.com/aldryn/aldryn-newsblog/blob/master/aldryn_newsblog/boilerplates/bootstrap3/templates/aldryn_newsblog/plugins/tags.html
you're right, that is what you're looking for, with article.tags.all:
{% if article.tags.exists %}
<ul style="margin-left: 0">
{% for tag in article.tags.all %}
<li class="tags">{{ tag.name }}</li>
{% if not forloop.last %}<span class="separator tags-separator">|</span> {% endif %}
{% endfor %}
</ul>
{% endif %}

That page contains no results Django ListView

I have the problem in Django 1.9
I have this problem when I go to the last result pagination
views.py
class UserList(ListView):
model = User
template_name = 'account/users.html'
paginate_by = 1
users.html
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
previous
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
{% endif %}
</span>
I've encountered this as well and the problem is that Paginator.page_range is 1-based.
https://docs.djangoproject.com/en/1.9/topics/pagination/#django.core.paginator.Paginator.page_range
I've used the following solution: (I'm using Foundation 6)
{% if is_paginated %}
<ul class="pagination text-center" role="navigation" aria-label="Pagination">
{% if page_obj.has_previous %}
<li class="pagination-previous">
<a href="?page={{ page_obj.previous_page_number }}">
<span>Previous</span>
</a>
</li>
{% else %}
<li class="pagination-previous disabled">
<span>Previous</span>
</li>
{% endif %}
{% for page in paginator.page_range %}
{% if paginator.num_pages != page %}
<li class="{% if page == page_obj.number %}active{% endif %}">
{{ page }}
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next and paginator.num_pages != page_obj.next_page_number %}
<li class="pagination-next">
<a href="?page={{ page_obj.next_page_number }}">
<span>Next</span>
</a>
</li>
{% else %}
<li class="pagination-next disabled">
<span>Next</span>
</li>
{% endif %}
</ul>
{% endif %}
Hope this helps! I initially based my code from https://ana-balica.github.io/2015/01/29/pagination-in-django/

How to recognize the first loop call in if statement?

I have code in template:
{% for p in products %}
{% if p.parent == None %}
<li class="{% if forloop.first %}active{% endif %}">
{{ p.name|upper }}
</li>
{% endif %}
{% endfor %}
In my case class "active" shows me in li with parent != None. I can't use [...]filter(parent=None) in view as I must have a complete list of products.
The problem is that if first object.parent in products =! None Django will think that the first iteration happened so that I will never add active to my class.
So I want to check when the first iteration with successful if statement happened. Any ways to do this?
You could recover the first element in the view in python, add it to the context and then test in your template :
{% for p in products %}
{% if not p.parent %}
<li class="{% if p == first_element %}active{% endif %}">
{{ p.name|upper }}
</li>
{% endif %}
{% endfor %}
{% with is_first=True %}
{% for p in products %}
{% if p.parent == None %}
<li class="{% if is_first %}active{% endwith % }{% endif %}">
{{ p.name|upper }}
</li>
{% endif %}
{% endfor %}
Can not test now - but perhaps that work!
You can put this on the objects themselves or as extra variable, when you build the context. Do code like this:
e.g. instead of:
ctx['products'] = Product.objects.all()
do something like this:
ctx['products'] = list(Product.objects.all())
is_first = True
for p in ctx['products']:
p.is_active = p.parent is None and is_first:
is_first = False
Then in the template, just do:
<li class="{% if p.is_active %}active{% endif %}">
{{ p.name|upper }}
</li>
If you don't want to write on the object, use extra variable
ctx['products'] = list(Product.objects.all())
is_first = True
for p in ctx['products']:
if p.parent is None and is_first:
ctx['active_id'] = p.id
break
Then in the template, just do:
<li class="{% if p.id == active_id %}active{% endif %}">
{{ p.name|upper }}
</li>
You can also use forloop.counter like this
{% for p in products %}
{% if forloop.counter == 0 %}
<li class="{% if is_first %}active{% endwith % }{% endif %}">
{{ p.name|upper }}
</li>
{% endif %}
{% endfor %}

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 - iterate number in for loop of a template

I have the following for loop in my django template displaying days. I wonder, whether it's possible to iterate a number (in the below case i) in a loop. Or do I have to store it in the database and then query it in form of days.day_number?
{% for days in days_list %}
<h2># Day {{ i }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
Django provides it. You can use either:
{{ forloop.counter }} index starts at 1.
{{ forloop.counter0 }} index starts at 0.
In template, you can do:
{% for item in item_list %}
{{ forloop.counter }} # starting index 1
{{ forloop.counter0 }} # starting index 0
# do your stuff
{% endfor %}
More info at: for | Built-in template tags and filters | Django documentation
Also one can use this:
{% if forloop.first %}
or
{% if forloop.last %}
{% for days in days_list %}
<h2># Day {{ forloop.counter }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
or if you want to start from 0
{% for days in days_list %}
<h2># Day {{ forloop.counter0 }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
from the docs https://docs.djangoproject.com/en/stable/ref/templates/builtins/#for
you can found it to count items you can use a counter like this
{% for job in jobs %}
<td>{{ forloop.counter }}</td>
<td>{{ job.title }}</td>
<td>{{ job.job_url }}</td>
{% endfor %}
{{ forloop.counter }} start counting from 1
{{ forloop.counter0 }} start counting from 0
Do like this,
{% for days in days_list %}
<h2># Day {{ forloop.counter }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}
[Django HTML template doesn't support index as of now], but you can achieve the goal:
If you use Dictionary inside Dictionary in views.py then iteration is possible using key as index. example:
{% for key, value in DictionartResult.items %} <!-- dictionartResult is a dictionary having key value pair-->
<tr align="center">
<td bgcolor="Blue"><a href={{value.ProjectName}}><b>{{value.ProjectName}}</b></a></td>
<td> {{ value.atIndex0 }} </td> <!-- atIndex0 is a key which will have its value , you can treat this key as index to resolve-->
<td> {{ value.atIndex4 }} </td>
<td> {{ value.atIndex2 }} </td>
</tr>
{% endfor %}
Elseif you use List inside dictionary then not only first and last iteration can be controlled, but all index can be controlled. example:
{% for key, value in DictionaryResult.items %}
<tr align="center">
{% for project_data in value %}
{% if forloop.counter <= 13 %} <!-- Here you can control the iteration-->
{% if forloop.first %}
<td bgcolor="Blue"><a href={{project_data}}><b> {{ project_data }} </b></a></td> <!-- it will always refer to project_data[0]-->
{% else %}
<td> {{ project_data }} </td> <!-- it will refer to all items in project_data[] except at index [0]-->
{% endif %}
{% endif %}
{% endfor %}
</tr>
{% endfor %}
End If ;)
//
Hope have covered the solution with Dictionary, List, HTML template, For Loop, Inner loop, If Else.
Django HTML Documentaion for more methods: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/
I think you could call the id, like this
{% for days in days_list %}
<h2># Day {{ days.id }} - From {{ days.from_location }} to {{ days.to_location }}</h2>
{% endfor %}