How to use for in another for cycle in django - python

I'm building some kind of list in which we have Section and Category assigned to the section.
In my view.py it looks like this:
args['sections'] = ShopSection.objects.all().order_by('name')
args['categories'] = ShopCategory.objects.all().order_by('-name')
And my template looks like this:
<div class="panel side-panel-1">
<h4 class="title1">Разделы</h4>
<ul class="clear-list">
<li class="">
Все разделы
</li>
{% for section in sections %}
<li class="">
<!--{{ section.name }}-->
<a class="" data-dropdown="autoCloseExample" aria-controls="autoCloseExample" aria-expanded="false">
{{ section.name }} ({{ section.shopcategory_set.count }}) {{section.shopcategory_set.id}} {{ section.id }}
</a>
<ul id="autoCloseExample" class="f-dropdown" data-dropdown-content tabindex="-1" aria-hidden="true" aria-autoclose="false" tabindex="-1">
{% for category in categories %}
{% if section.id == category.section_id%}
<li style="width: 100%;">{{ category.name }} sec={{section.id}} cat={{category.id}} catsec={{category.section_id}}</li>
{% else %}
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</ul>
The working page is here.
The problem is when I use {% if section.id == category.section_id %} I want to filter category list according to the section id, but section.id is not defining properly.
For example:
If I use {% if section.id > 3 %} then in cycle it defines section.id as 4
If i use {% if section.id < 3 %} then in cycle it defines section.id as 2
what i want is
-Section id-1
--Category1 which has section_id-1
--Category2 which has section_id-1
--Category3 which has section_id-1
-Section id-2
--Category4 which has section_id-2
--Category5 which has section_id-2
--Category6 which has section_id-2

If the ShopCategory has a ForeignKey to ShopSection, the cleanest and easiest way to do so is to change your second for loop like this so you don't have to check on the section_id:
{% for category in section.shopcategory_set.all %}
<li style="width: 100%;">{{ category.name }} sec={{section.id}} cat={{category.id}} catsec={{ section.id }}</li>
{% endfor %}

Related

Jinja template groupby sorting issue

In this code block, I have grouped by headings. But I want to sort the titles in array index order. Not alphabetically.
{% set list = widget.attributes.faq_item %}
{% for title_group in list|groupby('value.main_title') %}
<h2 class="account-sss__title">{{title_group.grouper}}</h2>
{% for item in title_group.list %}
<a href="#" class="account-sss__list--link js-link">
{{item.value.question}}
</a>
<div class="account-sss__content js-account-sss__content">
{{item.value.answer}}
</div>
{% endfor %}
{% endfor %}
I solved the problem.
{% set list = widget.attributes.faq_item %}
{% set Arr_titles = [] %}
{% for event in list %}
{% if event.value.main_title not in Arr_titles %}
{% do Arr_titles.append(event.value.main_title) %}
{% endif %}
{% endfor %}
{% for index in Arr_titles %}
<h2 class="account-sss__title">{{index}}</h2>
{% for item in list %}
{% if index == item.value.main_title %}
<a href="#" class="account-sss__list--link js-link">
{{item.value.question}}
</a>
<div class="account-sss__content js-account-sss__content">
{{item.value.answer}}
</div>
{% endif %}
{% endfor %}
{% endfor %}

Django python pagination always displaye the first 2, and last 2 pages

I have some pagination for a table. I have it so that it will only show 3 pages either side of the current page. However if I am on the 5th page, The first page disappears. I am trying to set it up so that the first two and last two pages of the pagination are always visible regardless of what the current page is.
code:
{% if is_paginated %}
<div class="pagination">
{% if current_page.has_previous %}
<a class="page-link" style="font-size: 24px; padding: 2px;" href="?page={{ current_page.previous_page_number }}">«</a>
{% else %}
<a class="page-link" style="font-size: 24px; padding: 2px;" href="">«</a>
{% endif %}
{% for i in current_page.paginator.page_range %}
{% if i == 1 %}
{% if current_page.number == i %}
<a class="page-link active" href="">{{ i }}</a>
{% else %}
<a class="page-link" href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% endif %}
{% if i == 2 %}
{% if current_page.number == i %}
<a class="page-link active" href="">{{ i }}</a>
{% else %}
<a class="page-link" href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% endif %}
{% if i != 1 and i != 2 %}
{% if current_page.number == i %}
<a class="page-link active" href="">{{ i }}</a>
{% else %}
{% if current_page.number|add:-4 == i %}
<a class="page-link" href="">...</a>
{% endif %}
{% if current_page.number|add:3 >= i and current_page.number|add:-3 <= i %}
<a class="page-link" href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% if current_page.number|add:4 == i %}
<a class="page-link" href="">...</a>
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% if current_page.has_next %}
<a class="page-link" style="font-size: 24px; padding: 2px;" href="?page={{ current_page.next_page_number }}">»</a>
{% else %}
<a class="page-link" style="font-size: 24px; padding: 2px;" href="">»</a>
{% endif %}
</div>
{% endif %}
Screenshot:
Update:
I have worked out a jank way of having the first two pages always showing but cannot get the last two pages to always show
I add some well place if statements to always display the first and last place.
I set it so that if i == 1 show the page in the pagination navbar. Then during the loop of i I remove the first page and last page using i != 1 and i != current_page.paginator.page_range|last.
Using current_page.paginator.page_range|last will get the last value in the range and then you do the same for the last page as you did for the first page.
Code:
{% for i in current_page.paginator.page_range %}
{% if i == 1 %}
{% if current_page.number == i %}
<a class="page-link active" href="">{{ i }}</a>
{% else %}
<a class="page-link" href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% endif %}
{% if i != 1 and i != current_page.paginator.page_range|last %}
{% if current_page.number == i %}
<a class="page-link active" href="">{{ i }}</a>
{% else %}
{% if current_page.number|add:-4 == i %}
<a class="page-link" href="">...</a>
{% endif %}
{% if current_page.number|add:3 >= i and current_page.number|add:-3 <= i %}
<a class="page-link" href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% if current_page.number|add:4 == i %}
<a class="page-link" href="">...</a>
{% endif %}
{% endif %}
{% endif %}
{% if i == current_page.paginator.page_range|last %}
{% if current_page.number == i %}
<a class="page-link active" href="">{{ current_page.paginator.page_range|last }}</a>
{% else %}
<a class="page-link" href="?page={{ current_page.paginator.page_range|last }}">{{ current_page.paginator.page_range|last }}</a>
{% endif %}
{% endif %}
{% endfor %}
Screenshot:

Filters not following on pagination in Django

I'm trying to set up pagination within my Django project but I can't find a way to make the filters (ptags in my case) follow to the next pages.
Ps; I use Django-haystack with faceting for filtering.
I have a custom forms.py
from haystack.forms import FacetedSearchForm
class FacetedProductSearchForm(FacetedSearchForm):
def __init__(self, *args, **kwargs):
data = dict(kwargs.get("data", []))
self.ptag = data.get('ptags', [])
super(FacetedProductSearchForm, self).__init__(*args, **kwargs)
def search(self):
sqs = super(FacetedProductSearchForm, self).search()
if self.ptag:
query = None
for ptags in self.ptag:
if query:
query += u' OR '
else:
query = u''
query += u'"%s"' % sqs.query.clean(ptags)
sqs = sqs.narrow(u'ptags_exact:%s' % query)
return sqs
That I pass in my Views:
class FacetedSearchView(BaseFacetedSearchView):
form_class = FacetedProductSearchForm
facet_fields = ['ptags']
template_name = 'search_result.html'
paginate_by = 3
context_object_name = 'object_list'
Here's my full search_result.html:
<div>
{% if page_obj.object_list %}
<ol class="row top20" id="my_list">
{% for result in page_obj.object_list %}
<li class="list_item">
<div class="showcase col-sm-6 col-md-4">
<div class="matching_score"></div>
<a href="{{ result.object.get_absolute_url }}">
<h3>{{result.object.title}}</h3>
<h5>{{ result.object.destination }}</h5>
<img src="{{ result.object.image }}" class="img-responsive">
</a>
<div class="text-center textio">
<ul class="tagslist">
<li class="listi">
{% for tags in result.object.ptags.names %}
<span class="label label-info"># {{ tags }}</span>
{% endfor %}
</li>
</ul>
</div>
</div>
</li>
{% endfor %}
</ol>
</div>
I'm able to pass the query which is a destination to the next page by adding this at the bottom of my html:
{% if is_paginated %}
<ul class="pagination pull-right">
{% if page_obj.has_previous %}
<li><i class="fas fa-angle-left"></i>Previous page</li>
{% else %}
<li class="disabled"><span><i class="fas fa-angle-left"></i>Previous page</span></li>
{% endif %}
{% if page_obj.has_next %}
<li>See more results<i class="fas fa-angle-right"></i></li>
{% else %}
<li class="disabled"><span>See more results<i class="fas fa-angle-right"></i></span></li>
{% endif %}
</ul>
{% endif %}
{% else %}
<p> Sorry, no result found for the search term <strong>{{query}} </strong></p>
{% endif %}
But If I try to add the ptags field within the pagination code by doing &ptags like this:
{% if is_paginated %}
<ul class="pagination pull-right">
{% if page_obj.has_previous %}
<li><i class="fas fa-angle-left"></i>Previous page</li>
{% else %}
<li class="disabled"><span><i class="fas fa-angle-left"></i>Previous page</span></li>
{% endif %}
{% if page_obj.has_next %}
<li>See more results<i class="fas fa-angle-right"></i></li>
{% else %}
<li class="disabled"><span>See more results<i class="fas fa-angle-right"></i></span></li>
{% endif %}
</ul>
{% endif %}
{% else %}
<p> Sorry, no result found for the search term <strong>{{query}} </strong></p>
{% endif %}
I get this error when I go to page 2 and the selected checkboxes filters (ptags) are not following:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/search/?q=las%20vegas&ptags=&page=2
Raised by: search.views.FacetedSearchView
How can I fix this?
Your template pagination code is removing the extra filter parameters, use this -
In your my_tags.py add this template tag:
#register.simple_tag(name='url_replace')
def url_replace(request, field, value):
d = request.GET.copy()
d[field] = value
return d.urlencode()
paginate as -
{% if is_paginated %}
<br>
<div class="row">
<div class="col-12">
<ul class="pagination float-right">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="?{% url_replace request 'page' page_obj.previous_page_number %}">«</a></li>
{% else %}
<li class="page-item disabled"><span class="page-link">«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active page-item"><span class="page-link">{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li class="page-item"><a class="page-link" href="?{% url_replace request 'page' i %}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="?{% url_replace request 'page' page_obj.next_page_number %}">»</a></li>
{% else %}
<li class="page-item disabled"><span class="page-link">»</span></li>
{% endif %}
</ul>
</div>
</div>
{% endif %}

Looping over items with Jinja, adding in div after every 5th item

Problem
I have a list of 100 golf courses and I'm looking to insert a div, containing an image for an ad after every fifth course. How would I go about doing this?
Update #1
content.html (Revised, newest version)
I've updated my original code snippet because off of leovp's
suggested edited below. I'm having trouble showing only {% if content.featured == "Test" %} and wondering how I should closing my if-else statement.
{% for content in COPY.courses %}
<div class="course course--featured">
<img src="" class="course__image image--region">
<div class="course__inner">
<div class="course__wrapper">
{% if content.state == "MO" %}
<p class="course__state">Missouri</p>
{% elif content.state == "IL" %}
<p class="course__state">Missouri</p>
{% endif %}
</div>
<div class="course__wrapper">
<p class="course__name name--region">{{ content.name }}</p>
</div>
<p class="course__desc">{{ content.description }}</p>
</div>
</div>
{% if loop.index % 5 == 0 %}
<div class="advertising advertising--inline">
<div class="ad ad--rect">
<div class="text-center hidden-xs">
<div id="fixed-leaderboard-region-top"
class="dfp-ad"
data-dfp-custom-pos="fixed-leaderboard-top, htf"
data-dfp-size="[728,90]">
</div>
</div>
<div class="text-center hidden-sm hidden-md hidden-lg">
<div id="fixed-leaderboard-region-top-mobile"
class="dfp-ad"
data-dfp-custom-pos="fixed-leaderboard-top, htf"
data-dfp-size="[320,50]">
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
content.html (Previous, old version for comparision)
I've looked into using batch from this Stack Overflow question that seemed similar, but I'm unsure if this solves my problem?
{% for content in COPY.courses %}
{% if content.featured == "Test" %}
<div class="course__inner">
<div class="course__wrapper">
{% if content.state == "MO"%}
<p class="course__state">Missouri</p>
{% elif content.state == "IL" %}
<p class="course__state">Illinois</p>
{% endif %}
</div>
<div class="course__wrapper">
<p class="course__name name--home">{{ content.name }}</p>
</div>
<p class="course__desc">{{ content.description }}</p>
</div>
{% endif %}
{% endfor %}
While iterating, you can get the current index and check if it's divisible by 5:
{% set count = 0 %}
{% for content in COPY.courses %}
{% if content.featured == "Test" %}
<div class="course course--featured">
<img src="" class="course__image image--home">
[...]
</div>
</div>
{% set count = count + 1 %}
{% if count % 5 == 0 %}
<!-- additional content once every 5 courses -->
{% endif %}
{% endif %}
{% endfor %}
NOTE: This approach no longer works after version 2.10.
For detail see:
How to increment a variable on a for loop in jinja template?

Access a flask template dictionary variable

I have a flask variable {{blogposts}} that outputs:
[{u'MONTH': 12, u'YEAR': 2016, u'post_name': u'data here', u'post_title': u'data here'},
{u'MONTH': 12, u'YEAR': 2016, u'post_name': u'data here', u'post_title': u"data here"},
{u'MONTH': 12, u'YEAR': 2016, u'post_name': u'data here', u'post_title': u'data here'}]
i have a flask template that outputs this like:
<ul>
{% for blogpost in blogposts %}
<li>
<a href="http://blog.site.com/wordpress/{{blogpost.MONTH}}/{{blogpost.YEAR}}/{{blogpost.post_name}}">
{{blogpost.post_title}}
</a>
</li>
{% else %}
<li>no blog posts right now...</li>
{% endfor %}
<div class="clearL"> </div>
</ul>
RENDERED HTML
<li>
<a href="http://blog.site.com/wordpress///">
</a>
</li>
<li>
<a href="http://blog.site.com/wordpress///">
</a>
</li>
<li>
<a href="http://blog.site.com/wordpress///">
</a>
</li>
<li>
<a href="http://blog.site.com/wordpress///">
</a>
</li>
I want to access the value for the month, year, post_name' and post_title (in this order), instead its outputting:
MONTH YEAR post_name post_title MONTH YEAR post_name post_title MONTH YEAR post_name post_title
How can I accomplish this?
Thank you
Try:
{% for blogpost in blogposts %}
<p> Month: {{ blogpost.MONTH }} </p>
<p> Year: {{ blogpost.YEAR }} </p>
<p> Name: {{ blogpost.post_name }}</p>
<p> Title: {{ blogpost.post_title }}</p>
{% endfor %}
Can try this !!
{% for row_index in blogposts %}
{% for key,value in row_index.iteritems() %}
{{key|safe}}
{{ value|safe }}
<br><br>
{% endfor %}
{% endfor %}
Even this can work
{% for row_index in blogposts %}
{% for key in row_index.iteritems() %}
{{key|safe}}
{{ row_index[key]|safe }}
<br><br>
{% endfor %}
{% endfor %}

Categories

Resources