after writing the view for my pagination in django, the button works fine, meaning that they load new pagesz but the problem is that all the posts still remains in all the new pages and that is not what's expected.
views.py
def ElementLists(request):
vectors = Vectors.objects.filter(status="published").order_by("?")
paginator = Paginator(vectors, 6)
page_number = request.GET.get('page')
vector_paginator = paginator.get_page(page_number)
elementlist.html
<li class="page-item">
{% if vector_paginator.has_previous %}
<a class="page-link" href="?page={{vector_paginator.previous_page_number}}" arialabel="Previous">
<span class="ti-arrow-left">Previous</span>
<span class="sr-only">Previous</span>
</a>
{% endif %}
</li>
<li class="page-item">
{% if vector_paginator.has_next %}
<a class="page-link" href="?page={{vector_paginator.next_page_number}}" aria-label="Next">
<span class="ti-arrow-right">Load More</span>
<span class="sr-only">Next</span>
</a>
{% endif %}
</li>
I later got a fix for it
when looping thorught your posts in template, it should now be this
before
{% for post in posts %}
...code here
{% endfor %}
Now
{% for post in posts_paginator %}
...code here
{% endfor %}
Related
I am currently working on a django blog and I've coded a search bar where you type something and, if there's any post that contains what you've typed in the title, it should appear all the posts. This part is perfectly well-written. However, there's an error with the pagination. As you'll see in the views.py. The maximum num of posts per page is 3. However, you can see there's four. However, the paginator detects there should be another page for the fourth posts. Here's an image that shows that.
Here's the views.py:
class ElementSearchView(View):
elements_list = Element.objects.all()
def get(self, request, *args, **kwargs):
paginator = Paginator(self.elements_list, 3)
page_request_var = 'page'
page = request.GET.get(page_request_var)
try:
paginated_queryset = paginator.page(page)
except PageNotAnInteger:
paginated_queryset = paginator.page(1)
except EmptyPage:
paginated_queryset = paginator.page(paginator.num_pages)
queryset = Element.objects.all()
query = request.GET.get('q')
if query:
queryset = queryset.filter(
Q(title__icontains=query)
).distinct()
context = {
'query': queryset,
'queryset': paginated_queryset,
'page_request_var': page_request_var,
}
return render(request, 'periodic/search_results_table.html', context)
And here's the html template: The pagination is at the end of the template.
{% load static %}
<html>
{% include 'periodic/head_search.html' %}
<body>
{% include 'periodic/header.html' %}
<br>
<br>
<div class="container">
<div class="row">
<!-- Latest Posts -->
<main class="posts-listing col-lg-8">
<div class="container">
<div class="row">
<!-- post -->
{% for element in query %}
<div class="post col-xl-6 wrap-login100">
<div class="post-thumbnail"><img src="{{ element.thumbnail.url }}" alt="..." class="img-fluid"></div>
<div class="post-details">
<a href="{{ element.get_absolute_url }}">
<h3 class="h4">{{ element.title }}</h3></a>
</div>
</div>
{% endfor %}
</div>
<!-- Pagination -->
<nav aria-label="Page navigation example">
<ul class="pagination pagination-template d-flex justify-content-center">
{% if queryset.has_previous %}
<li class="page-item"> <i class="fa fa-angle-left"></i></li>
{% endif %}
<li class="page-item">{{ queryset.number }}</li>
{% if queryset.has_next %}
<li class="page-item"> <i class="fa fa-angle-right"></i></li>
{% endif %}
</ul>
</nav>
{% if is_paginated %}
<nav aria-label="Page navigation example">
<ul class="pagination pagination-template d-flex justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item"> <i class="fa fa-angle-left"></i></li>
{% endif %}
<li class="page-item">{{ page_obj.number }}</li>
{% if page_obj.has_next %}
<li class="page-item"> <i class="fa fa-angle-right"></i></li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</main>
</body>
{% include 'periodic/scripts_search.html' %}
</html>
As the user #ikilnac mentioned,
you are looping over the original queryset and not the paged one in your template
That simply means that in your loop, you do this
{% for element in query %}
<div class="post col-xl-6 wrap-login100">
<div class="post-thumbnail"><img src="{{ element.thumbnail.url }}" alt="..." class="img-fluid"></div>
<div class="post-details">
<a href="{{ element.get_absolute_url }}">
<h3 class="h4">{{ element.title }}</h3></a>
</div>
</div>
{% endfor %}
And then after that, you are using the tag in the form of {% if queryset.has_previous %} with the original queryset rather than the paged one in the template (the query).
There's a good example of it here - Paginate with Django
I'm trying to add the paginate option on my posts page from my blog website. I want to implement the paginator on my view function that renders the page and I found this exemple from Django's doc but it doesn't work. Any help ?
view function:
def blog(request):
posts = Post.objects.all().order_by('-date_posted')
paginator = Paginator(posts, 2)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
context = {
'posts': posts,
'page_obj': page_obj,
'title': 'Blog',
'banner_page_title': 'Blog',
'page_location': 'Home / Blog'
}
return render(request, 'blog/blog.html', context)
html rendering
<nav class="blog-pagination justify-content-center d-flex">
<ul class="pagination">
{% if is_paginated %}
{% if page_obj.has_previous %}
<li class="page-item">
<a href="?page={{ page_obj.previous_page_number }}" class="page-link" aria-label="Previous">
<span aria-hidden="true">
<span class="ti-arrow-left"></span>
</span>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
{{ num }}
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
{{ num }}
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a href="?page={{ page_obj.next_page_number }}" class="page-link" aria-label="Next">
<span aria-hidden="true">
<span class="ti-arrow-right"></span>
</span>
</a>
</li>
{% endif %}
{% endif %}
</ul>
</nav>
the url route
path('blog/', blog, name='blog'),
Remove the {% if is_paginated %} as it isn't returning any value and that is why you don't see any of the numbers (don't forget to remove the closer if {% endif %})
You can access your paginated objects from the page_obj
{% for post in page_obj %}
{{ post }}
{% endfor %}
Here is the HTML with the changes
{% for post in page_obj %}
{{ post.text }}<br>
{% endfor %}
<nav class="blog-pagination justify-content-center d-flex">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a href="?page={{ page_obj.previous_page_number }}" class="page-link" aria-label="Previous">
<span aria-hidden="true">
<span class="ti-arrow-left"></span>
</span>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
{{ num }}
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
{{ num }}
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a href="?page={{ page_obj.next_page_number }}" class="page-link" aria-label="Next">
<span aria-hidden="true">
<span class="ti-arrow-right"></span>
</span>
</a>
</li>
{% endif %}
</ul>
</nav>
I have a template which includes 4 different paginators that only differ in context variables (tasks_today, tasks_tomorrow, ... etc.), and I want to minimise code repetition so I don't have 4 different paginator templates.
Template:
<div class="wrapper">
<h3>Today</h3>
<table>
{% if tasks_today %}
{% for task in tasks_today %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_today.html' %}
{% else %}
<p>No tasks for today.</p>
{% endif %}
</table>
<h3>Tomorrow</h3>
<table>
{% if tasks_tomorrow %}
{% for task in tasks_tomorrow %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_tomorrow.html' %}
{% else %}
<p>No tasks for tomorrow.</p>
{% endif %}
</table>
<h3>Upcoming</h3>
<table>
{% if tasks_upcoming %}
{% for task in tasks_upcoming %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_upcoming.html' %}
{% else %}
<p>No upcoming tasks.</p>
{% endif %}
</table>
<h3>Past</h3>
<table>
{% if tasks_past %}
{% for task in tasks_past %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_past.html' %}
{% else %}
<p>No tasks in the past.</p>
{% endif %}
</table>
</div>
paginator_today:
{% load url_replace %}
{% if tasks_today %}
<div class='paginator'>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if tasks_today.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_today=1 %}" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">begin</span>
</a>
</li>
{% endif %}
{% for n in tasks_today.paginator.page_range %}
{% if tasks_today.number == n %}
<li class="page-item active">
<span class="page-link">{{ n }}
<span class="sr-only">(current)</span>
</span>
</li>
{% elif n > tasks_today.number|add:'-3' and n < tasks_today.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_today=n %}">{{ n }}</a>
</li>
{% endif %}
{% endfor %}
{% if tasks_today.has_next %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_today=tasks_today.paginator.num_pages %}" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">end</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
{% endif %}
paginator_tomorrow:
{% load url_replace %}
{% if tasks_tomorrow %}
<div class='paginator'>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if tasks_tomorrow.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_tomorrow=1 %}" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">begin</span>
</a>
</li>
{% endif %}
{% for n in tasks_tomorrow.paginator.page_range %}
{% if tasks_tomorrow.number == n %}
<li class="page-item active">
<span class="page-link">{{ n }}
<span class="sr-only">(current)</span>
</span>
</li>
{% elif n > tasks_tomorrow.number|add:'-3' and n < tasks_tomorrow.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_tomorrow=n %}">{{ n }}</a>
</li>
{% endif %}
{% endfor %}
{% if tasks_tomorrow.has_next %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_tomorrow=tasks_tomorrow.paginator.num_pages %}" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">end</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
{% endif %}
What can I do?
url_replace.py:
from django.utils.http import urlencode
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def url_replace(context, **kwargs):
query = context['request'].GET.dict()
query.update(kwargs)
return urlencode(query)
You can use the with keyword to set certain variables inside your include template:
{% include 'todo/paginator.html' with tasks=tasks_today page='page_today' %}
You can then replace references to tasks_today in you paginator template to tasks, as well as the reference to page_today to page
Edit: The call to url_replace is problematic, since it uses kwargs, and a call like {% url_replace page_today = x %}, will be equivalent to a call to urlreplace(context, **{'page_today' : x}).
Simply calling url_replace with page = x will not work correctly, since it will pass a keyword argument with the name of page instead of the value of page
The naive solution would be to pass a page variable to the paginator.html and call {% urlreplace **{page : 20} %}, but the Django template engine does not allow packing kwargs.
I think the best way to go here is to create a url_replace_single function, since in this use case you only replaces one value.
To do this, you'll need to define a field and value parameter on you url_replace function:
#register.simple_tag(takes_context=True)
def url_replace(context, field, value, **kwargs):
query = context['request'].GET.dict()
query_dict = { field : value}
query.update(query_dict)
return urlencode(query)
Then call the function from your template like this:
{% url_replace field=page value=x %}
The only downside is that this will only let you replace one query parameter in your url.
i'm create template for search this table.it can search but click for next page is error in the picture
For Error
Same mycode.
#view.py
def search(request):
query = request.GET.get('q1')
qselect = request.GET.get('q2')
qs = Record_data.objects.filter(Q(invoice_no__startswith=query) | Q(product=query))
page = request.GET.get('page', 1)
paginator = Paginator(qs, 5)
try:
page1 = paginator.page(page)
except PageNotAnInteger:
page1 = paginator.page(1)
except EmptyPage:
page1 = paginator.page(paginator.num_pages)
template_name = 'status.html'
context = {'object_list': page1}
#
page function
#html code
{% if object_list.has_other_pages %}
<ul class="pagination">
{% if object_list.has_previous %}
<li class="page-item"><a class="page-link" href="?page={{ object_list.previous_page_number }}">Previous</a></li>
{% else %}
<li class="page-item disabled"><span class="page-link">Previous</span></li>
{% endif %}
{% for i in object_list.paginator.page_range %}
{% if object_list.number == i %}
<li class="page-item active"><span class="page-link">{{ i }}</span></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if object_list.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ object_list.next_page_number }}">Next</a></li>
{% else %}
<li class="page-item disabled"><span class="page-link">Next</span></li>
{% endif %}
</ul>
{% endif %}
Rather than hard coding why not use the data tables jquery plugin?
https://datatables.net
use the above links and customise to your use ... i aint marketing but its simple to use a jquery plugin for data tables and hard coding will be easy for whole page Pagination.
Code:
class MyObjects(LoginRequiredMixin, ListView):
model = AllObjects
template_name = "my_objects.html"
paginate_by = 10
def get_queryset(self, *args, **kwargs):
queryset = super(MyObjects, self).get_queryset()
return queryset.filter(added_by=self.request.user).order_by('-last_modified')
I have a view that lists user's addings to a table. The problem is pagination is not working properly. I think it is because each time django renders the page, it filters the queryset again, causing only first 10 items to be listed. What can be done to handle this problem? Or should i not use generic view for doing such thing?
Template:
<table>
{% for obj in object_list %}
<tr>
<td>
{{ obj.name}}
</td>
</tr>
{% endfor %}
</table>
<nav aria-label="Page navigation">
<ul class="pagination">
<li class="page-item {% if not page_obj.has_previous %}disabled{%endif%}">
<a class="page-link" {% if page_obj.has_previous %} href="?sayfa={{ page_obj.previous_page_number }}" {% endif %} aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% for page in page_obj.paginator.page_range %} {% if page == page_obj.number %}
<li class="page-item active"><a class="page-link" href="#">{{ page }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?sayfa={{ page }}">{{ page }}</a></li>
{% endif %} {% endfor %}
<li class="page-item {% if not page_obj.has_next %}disabled{%endif%}">
<a class="page-link" {% if page_obj.has_next %}href="?sayfa={{ page_obj.next_page_number }}" {% endif %} aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
I found my mistake. In my template, i used the link "?sayfa={{ page }}". ("sayfa" means page in Turkish, so it's localized version) It's a leftover from my previous pagination which i made with function based view. One way to fix is changing all "sayfa"'s to "page" but since this is not great for localization purposes adding page_kwarg = "sayfa" to my view fixed the problem. Thanks for the answers!