Django pagination - example from documentation. How to display with all sites number? - django

This is example from documentation Django:
def listing(request):
contact_list = Contacts.objects.all()
paginator = Paginator(contact_list, 25) # Show 25 contacts per page
page = request.GET.get('page')
try:
contacts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
contacts = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
contacts = paginator.page(paginator.num_pages)
return render_to_response('list.html', {"contacts": contacts})
template:
{% for contact in contacts %}
{# Each "contact" is a Contact model object. #}
{{ contact.full_name|upper }}<br />
...
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
This display for example:
Page 2 of 3. next
How to display it in this way:
previous 1 <b>2</b> 3 Next
Current page with html <b> mark.
?

You can try this:
{% for num in contacts.paginator.page_range %}
{% ifequal num contacts.number %}
<span class="current"><b>{{ num }}</b></span>
{% else %}
{{ num }}
{% endifequal %}
{% endfor %}

Below example is actually for class based views but would work fine.
CSS is Twitter Bootstrap V3.0.0.
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>«</li>
{% else %}
<li class="disabled">«</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% ifequal num page_obj.number %}
<li class="active">{{ num }}<span class="sr-only">(current)</span></li>
{% else %}
<li>{{ num }}</li>
{% endifequal %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled">»</li>
{% endif %}
</ul>
{% endif %}

This is mine.
{% if page.paginator.num_pages > 1 %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if page.paginator.num_pages != 1 %}
<li class="page-item"><a class="page-link" href="?page=1">First</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">First</a></li>
{% endif %}
{% if page.has_previous %}
<li class="page-item"><a class="page-link" href="?page={{ page.previous_page_number }}">«</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">«</a></li>
{% endif %}
{% for i in page.paginator.page_range %}
{% if page.number == i %}
<li class="page-item active"><a class="page-link" href="#">{{ i }} <span class="sr-only">(current)</span></a></li>
{% elif page.number > i|add:"-5" and page.number < i|add:"+5"%}
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ page.next_page_number }}">»</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">»</a></li>
{% endif %}
{% if page.paginator.num_pages != page.number %}
<li class="page-item"><a class="page-link" href="?page={{ page.paginator.num_pages }}">Last</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Last</a></li>
{% endif %}
</ul>
</nav>
{% endif %}
Looks like

If someone needs Bootstap 4 Alpha 5 version of code.
Also I did two changes:
I do not like duplicates of pages, so I changed in my case /profiles/?page=1 to simple /profiles/.
I have lots of pages, so I do not show all pages. I show just: The 1st, the last, current and +-3 pages from the current one, and every 10th page.
If you need just all pages with Bootstrap 4 without my modifications, just remove unnecessary parts of code (everything is commented).
{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination">
<!-- << PREVIOUS PART -->
<!-- << Disable 'Previous' page button if you are at the 1st page -->
{% if not page_obj.has_previous %}
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-label="Previous">
<!-- << If you are at the 2nd page,
'Previous' page button will get '/profiles/' url instead of '/profiles/?page=1' -->
{% elif page_obj.previous_page_number == 1 %}
<li class="page-item">
<a class="page-link" href="{{ profiles_1st_page_url }}" aria-label="Previous">
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
{% endif %}
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span>
</a>
</li>
<!-- PAGES PART -->
{% for num in page_obj.paginator.page_range %}
<!-- Active page -->
{% if num == page_obj.number %}
<li class="page-item active">
<a class="page-link" href="#">{{ num }}<span class="sr-only">(current)</span></a>
</li>
{% else %}
<li class="page-item">
<!-- For the 1st page we do not use ?page=1 -->
{% if num == 1 %}
<a class="page-link" href="{{ profiles_1st_page_url }}">{{ num }}</a>
{% else %}
<!-- Show current page and +-3 pages -->
{% if num|add:"-3" <= page_obj.number and page_obj.number <= num|add:"3" %}
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
<!-- Shows every 10th page and the last page -->
{% elif num|divisibleby:"10" or num == page_obj.paginator.num_pages %}
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
{% endif %}
{% endif %}
</li>
{% endif %}
{% endfor %}
<!-- >> NEXT PART -->
{% if not page_obj.has_next %}
<!-- << Disable 'Next' page button if you are at the last page -->
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-label="Next">
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
{% endif %}
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
</ul>
</nav>
{% endif %}
And it looks like:

Related

Django template large data pagination link issue

I am using the django paginator in my template. Its working ok with less data, but not working good when there's large numbers of pages.
Pagination links code is given bellow:
<div class="paginationWrapper mt-3">
{% if match_list.paginator.num_pages > 1 %}
<ul class="pagination">
{% if match_list.has_previous %}
<li>
<a href="?p={{ match_list.previous_page_number }}
{% if request.GET.search %}&search={{ request.GET.search }}
{% endif %}" class="page-link"><i class="fas fa-angle-double-left"></i></a>
</li>
{% endif %}
{% for j in match_list.paginator.page_range %}
{% if match_list.number == j %}
<li class="active"><a class="page-link" href="#">{{ j }}</a></li>
{% else %}
<li><a href="?p={{ j }}{% if request.GET.search %}&search={{ request.GET.search }}
{% endif %}" class="page-link">{{ j }}</a></li>
{% endif %}
{% endfor %}
{% if match_list.has_next %}
<li>
<a href="?p={{ match_list.next_page_number }}
{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}
" class="page-link"><i class="fas fa-angle-double-right"></i></a>
</li>
{% endif %}
</ul>
{% endif %}
</div>
After this i am gettin the links in my template like :
what i actually want is i want to display only 10 links after that ... to show more can anyone please help me relatred this i am stuck here
https://docs.djangoproject.com/en/3.1/topics/pagination/#paginating-a-listview
try this
{% load core %} // core here is template tag
{% if match_list.paginator.num_pages > 1 %}
<ul class="pagination justify-content-center">
{% if match_list.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% param_replace page=1 %}">
First
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">
First
</a>
</li>
{% endif %}
{% if match_list.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% param_replace page=match_list.previous_page_number %}">
«
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">
«
</a>
</li>
{% endif %}
{% for i in match_list.paginator.page_range %}
{% if match_list.number == i %}
<li class="page-item active">
<a class="page-link" href="#">{{ i }} <span class="sr-only">(current)</span>
</a>
</li>
{% elif match_list.number > i|add:"-5" and match_list.number < i|add:"+5"%}
<li class="page-item"><a class="page-link" href="?{% param_replace page=i %}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if match_list.has_next %}
<li class="page-item">
<a class="page-link" href="?{% param_replace page=match_list.next_page_number %}">
»
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">
»
</a>
</li>
{% endif %}
{% if match_list.paginator.num_pages != match_list.number %}
<li class="page-item">
<a class="page-link" href="?{% param_replace page=match_list.paginator.num_pages %}">
Last
</a>
</li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Last</a></li>
{% endif %}
</ul>
{% endif %}
custom template tag
#register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):
"""
"""
d = context['request'].GET.copy()
for k, v in kwargs.items():
d[k] = v
for k in [k for k, v in d.items() if not v]:
del d[k]
return d.urlencode()
output

Django Pagination - Object list not looping in template

I'm attempting to use pagination on my notifications page for a user (list of all notifications). When I add the code for pagination:
def notificationList(request, pk):
notifications = Notification.objects.all()
paginator = Paginator(notifications, 5)
page = request.GET.get('page')
try:
notifications = paginator.page(page)
except PageNotAnInteger:
notifications = paginator.page(1)
except EmptyPage:
notifications = paginator.page(paginator.num_pages)
context = {'notifications': notifications }
return render(request, 'user/notifications.html', context)
The result is this:
However, when I comment out all pagination related code in views.py, all the notifications appear on the page (pagination appears). So I know it's not that I'm not accessing my notification object list incorrectly/returning an empty queryset. Here is the notifications.html pagination code:
{% if notifications.has_other_pages %}
<ul class="pagination justify-content-center mb-4">
{% if notifications.has_previous %}
<li class="page-item"><a class="page-link" href="?page={{ notifications.previous_page_number }}">«</a></li>
{% else %}
<li class="disabled page-item"><span class="page-link">«</span></li>
{% endif %}
{% for i in notifications.paginator.page_range %}
{% if notifications.number == i %}
<li class="active page-item"><span class="page-link">{{ i }} <span class="sr-only page-item">(current)</span></span></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if notifications.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ notifications.next_page_number }}">»</a></li>
{% else %}
<li class="disabled page-item"><span class="page-link">»</span></li>
{% endif %}
</ul>
{% endif %}
Here is where I render the notifications in the template:
{% for notification in notifications %}
<div class="row">
<div class="col">
{% if notification.read == False %}
<span class="badge badge-primary">New</span>
{% elif notification.read == True %}
<span class="badge badge-success">Read</span>
{% endif %}
</div>
<div class="col">
<a class="btn btn-sm btn-info" href="{% url 'offer-details' notification.offer_id %}">View</a>
</div>
<div class="col">
{% if notification.type_of_notification == "O" %}
<p>An offer has been made for one of your repairs!</p>
{% elif notification.type_of_notification == "P" %}
<p>A payment has been made on a repair!</p>
{% elif notification.type_of_notification == "OR" %}
<p>Sorry, your offer for a repair has been rejected.</p>
{% elif notification.type_of_notification == "OC" %}
<p>An offer for your repair has been canceled!</p>
{% endif %}
</div>
<div class="col">
{{notification.created_at}}
</div>
</div>
<hr>
{% endfor %}

How to fix this TemplateSyntaxError at error in django

I get this error
TemplateSyntaxError at /
add requires 2 arguments, 1 provided
Screenshot:
ERROR SCREENSHOT
I want to add pagination there but i get this error again and again
Here is my html file
<div class="pagination">
{% if buy_list.has_previous %}
<li class="page-item"><a class="page-link" href="?page=1"></a></li>
<li class="page-item"><a class="page-link" href="?page={{ buy_list.previous_page_number }}"></a></li>
{% endif %}
{% for num in buy_list.paginator.page_range %}
{% if buy_list.number == num %}
<strong>{{ num }}</strong>
{% elif num > buy_list.number|add: '-3' and num < buy_list.number|add: '3' %}
{{num}}
{% endif %}
{% endfor %}
{% if buy_list.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ buy_list.next_page_number }}"></a></li>
<li class="page-item"><a class="page-link" href="?page={{ buy_list.paginator.num_pages }}"></a></li>
{% endif %}
Thanks
Remove spaces after the add: built-in filter in your template.
buy_list.number|add:"-3"
buy_list.number|add:"3"

How to paginate bootstrap cards with django

I am getting my query results based on user selection and showing them on bootstrap cards in django. I am using django Paginator to display at max 6 results per page (currently set to 1 for testing). The problem is my Paginator is showing all the results on all the pagination pages.
Could someone please help me??
View:
def results(request):
results = []
query_city = request.GET.get('city')
print(query_city)
all_records = hotel.objects.all()
for states in all_records:
if states.confirm_approval and states.space_state == query_city:
print(states)
results.append(states)
paginator = Paginator(results,1)
page = request.GET.get('page')
try:
items = paginator.page(page)
except PageNotAnInteger:
items = paginator.page(1)
except EmptyPage:
items = paginator.page(paginator.num_pages)
index = items.number - 1
max_index = len(paginator.page_range)
start_index = index - 5 if index >= 5 else 0
end_index = index + 5 if index <= max_index - 5 else max_index
page_range = paginator.page_range[start_index:end_index]
context = {
'results':results,
'items':items,
'page_range':page_range,
}
return render(request, 'results/results.html', context)
Html Template:
% for result in results %}
{% if forloop.counter0|divisibleby:3 %} <div class="row"> {% endif %}
<div class="col">
<div class="card-deck" id="cardholder">
<div class="card" style="max-width: 20rem;">
<img class="card-img-top" src="{% static 'mainpage/img/bg/books.jpg' %}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{ result.hotel_name }}</h5>
</div>
<div class="card-footer">
Show more
</div>
</div>
</div>
</div>
{% if forloop.counter|divisibleby:3 or forloop.last %}</div><!-- row closing -->{% endif %}
{% endfor %}
{% if items.has_other_pages %}
<nav aria-label="">
<ul class="pagination justify-content-center">
{% if items.has_previous %}
<li class=class="page-item">
<a class="page-link"
href="?page={{items.previous_page_number}}{% if request.GET.city %}&city={{ request.GET.city }}{% endif %}"
tabindex="-1">Previous</a>
</li>
{% else %}
<li class="page-item disabled"><a class="page-link">Previous</a></li>
{% endif %}
{% for i in page_range %}
{% if items.number == i %}
<li class="page-item active"><a class="page-link" href="#">{{i}} <span
class="sr-only">(current)</span></a>
</li>
{% else %}
<li class="page-item"><a class="page-link"
href="?page={{i}}{% if request.GET.city %}&city={{ request.GET.city }}{% endif %}">{{i}}</a>
</li>
{% endif %}
{% endfor %}
{% if items.has_next %}
<li class="page-item">
<a class="page-link" aria-label="Next"
href="?page={{items.next_page_number}}{% if request.GET.city %}&city={{ request.GET.city }}{% endif %}">Next</a>
</li>
{% else %}
<li class="page-item disabled"><a class="page-link">Next</a></li>
{% endif %}
</ul>
</nav>
{% endif %}
brtt3000 from r/djangolearning helped me over redit.
This was his answer: You're looping over the wrong context variable,
change it to items.
{% for result in results %} I suspected this as soon as I saw you had
both items and results in the context :)
For anyone whos gets here, remember to pass in the paginated variable.

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/