I have a for loop inside another for loop and im trying to get the index (forloop.counter) from the inner loop. Django is for some reason giving me only the outer index.
{% for category in categories %}
{% for product in products %}
{% if product.category.name == category.name %}
<p>This is the amount of products inside this category: {{ forloop.counter }}<p>
{% endif %}
{% endfor %}
{% endfor %}
You can use forloop.parentloop to get to the outer forloop, so in this case {{forloop.parentloop.counter}}. {{forloop.counter}} gives me the inner loop already.
Return to the category view (e.g. in views.py) and add an annotation:
from django.db.models import Count
categories = Category.objects.annotate(num_products=Count('product'))
Remember to include the annotation in this view's context:
context.update({'categories': categories})
return render(request, 'myapp/categories.html', context)
Now, tweak your template to show the counts:
{% for category in categories %}
<p>This is the amount of products inside this category: {{ category.num_products }}<p>
{% endfor %}
Related
I'm looping through to different categories and rendering results (of its name and its associated pages). This code is rendering correctly.
{% for category in categories %}
<div class="row">
<div class="col-lg-4">
<h3>{{category.category_name}}</h3>
{% for page in category.page_set.all %}
<p><a href="{{page.get_absolute_url}}">{{page.page_title}}</p>
{% endfor %}
</div>
</div>
{% endfor %}
I'd like to catch an specific element inside the for loop (to be precise the 4th one in the forloop counter) and customize it (adding some html and text only to that one). I tried using the forloop.counter like this:
{% if forloop.counter == 4 %}
<!-- modified content -->
{% endif %}
But there isn't any results (not showing any changes). Is there any way to do this?
As per my understanding of your question. You can try it soo:
You can place this inside your for loop so that whenever you it iterates and by that you can use your if value to do some operations for specific value.
{% if some_variable == some_value %}
{{ do_something }}
{% endif %}
I don't really know how to phrase my question, but what I'm trying to do is add a title between items to split them into obvious categories on my template. I would like to do this:
{# set variable "current_category" to an empty value first #}
{% for item in items %}
{% if item.category != current_category %}
{{ current_category = item.category }} {# <-- How to do that? #}
<h1>{{ item.category }}</h1>
{% endif %}
<p>{{ item.name }}</p>
{% endfor %}
Then end up with:
<h1>Cat 1</h1>
<p>item</p>
<p>item</p>
...
<h1>Cat 2</h1>
<p>item</p>
..
I saw on similar answers that there are things called custom filters and simple tags but it seems really complicated for something very simple. Is this really the only way to do that?
NOTE: I already ordered the items by category of course
I think you're looking for Django's regroup template tag, which does exactly what you're asking for.
{% regroup items by category as grouped_items %}
{% for category, item_list in grouped_items %}
<h1>{{ category }}</h1>
{% for item in item_list %}
<p>{{ item.name }}</p>
{% endfor %}
{% endfor %}
Is there a way to say to Django to hide/remove (show a blank space) for fields that got same values as previous row?
i.e.: if now is equal for differents Articles can it be show only for the first of the group?
from django.views.generic.list import ListView
from django.utils import timezone
from articles.models import Article
class ArticleListView(ListView):
model = Article
def get_context_data(self, **kwargs):
context = super(ArticleListView, self).get_context_data(**kwargs)
context['now'] = timezone.now()
return context
<h1>Articles</h1>
<ul>
{% for article in object_list %}
<li>{{ article.pub_date|date }} - {{ article.headline }}</li>
{% empty %}
<li>No articles yet.</li>
{% endfor %}
</ul>
Article - now
a - 2017-01-01
b -
c - 2017-01-02
d -
Is this possible from view or directly in template?
You can use ifchanged which:
Checks if a value has changed from the last iteration of a loop.
as follows:
<h1>Articles</h1>
<ul>
{% for article in object_list %}
<li>{{ article.headline }} - {% ifchanged article.pub_date|date %}
{{ article.pub_date|date }} {% endifchanged %}
</li>
{% empty %}
<li>No articles yet.</li>
{% endfor %}
</ul>
This will check in each iteration the value of article.pub_date and only when that value changes it will be displayed.
Good luck :)
I want to display only one value from for loop in template.
Let's say I have this:
{% for category in categories %}
{{category.name}}
See All
{% endfor %}
If I have 5 category then See All in being printed 5 times. How can I only print it once..
Thanx in adnvance..
You should have a main page with all your categories in which you will send it context['categories']
And if you don't need to have a link between your categories in detail just send the current category in the views.py :
context['category']
EDIT:
If all you want to do is break in the loop you can't in django template but you can use slice :
{% for category in categories|slice:":1" %}
It will just go through the loop once
You have to limit the object and send that object to template
tempalte_var['content'] = Categories.objects.all()[:5]
Not the best way but check this:
{% for category in categories %}
{% if categories|length > 1 %}
See All
{% else %}
{{categories[1].name}}
{{category.name}}
{% endif %}
{% endfor %}
This code will print the first element in Category
{% for category in categories %}
{% if categories | first %}
{{category.name}}
See All
{% endif %}
{% endfor %}
I'd like to show my top level categories if the parent is equal to one. The topcats is a queryset that contains category items. However the code starred below is not working. It is not finding any cat items with parent = 1. Any idea why?
{% for cat in topcats %}
**{% if cat.parent == 1 %}**
<h3>{{ cat.category }}</h3>
{% for each in topcats %}
{% if each.parent == cat.id %}
<h5>{{ each }}</h5>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
Note: parent is a TreeForeignKey in the database
I'd say cat.parent is a model object.
This should work for you:
{% if cat.parent.pk == 1 %}
However, this is quite hackish, as the parent node's id does not necessarily have a value of 1. The is_root_node() method is a better approach:
{% if cat.parent.is_root_node %}