how to do ajax pagination in Django?

Viewed 4500

!! I have a model named blog !!

class blog(models.Model):
    image          = models.ImageField(upload_to='Media/awards')
    title          = models.CharField(max_length=255,blank=True)
    content        = models.TextField(blank=True)

and in the frontend I have

<div class="col-md-6" id= "mydiv">
<div>

 <!-- pagination design start -->
            <div class="blog_bottom_pagination">
              <div class="counter">/</div>
              <button class="paginate left"><i class="fas fa-angle-left"></i></button>
              <button class="paginate right">
                <i class="fas fa-angle-right"></i>
              </button>
            </div>
  <!-- pagination design end -->

I don't find any reference how i implement pagination without page refresh and render two data at a time in that div section. and paginate right and left by the button for getting next two data and will replace those previous data in that div.... thank you in advance

3 Answers

So the view side should look like this:

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

blog_objects= Blog.objects.filter()

paginator = Paginator(blog_objects, 10)
page = request.GET.get('page', 1)

try:
    blogs = paginator.page(page)
except PageNotAnInteger:
    blogs = paginator.page(1)
except EmptyPage:
    blogs = paginator.page(paginator.num_pages)

page_list = blogs.paginator.page_range

Button to trigger ajax function on template:

{% for i in page_list %}
<button onclick="ajax_function('{{i}}','{{title}}')">{{i}}</button>

Note "i" is the page number for the ajax function and "title" is the argumant for query.

Ajax function from template is at the end...

Ajax view:

def paginate(request):
    page= request.GET.get('page', None)
    title= request.GET.get('title', None)
    
       starting_number= (page-1)*10
       ending_number= page*10

    "here you should multiply the 'page' by the number of results you want per page, in my example it's 10"
      


     result= Blog.objects.filter(title= title)[starting_number:ending_number]
    
"By [starting_number:ending_number] we specify the interval of results. Order them by date or whatever you want"
                data={result}
   
    return JsonResponse(data)

The result object is now sent to the html side, now its time for the ajax function:

function ajax_function(page,title) {
    $.ajax({
        url: '/ajax/paginate/',
        type: "get",
        data: {
            'page': page,
            'title': title,

        },
        dataType: 'json',
        success: function (data) {
             $('#id-of-your-choice').empty();
             for (i = 0; i < data.result.length; i++) {
             $('#id-of-your-choice').append(i)
        }
"at first the function cleans the old childs of the element on which you display your results then it appends the new page's content by iterating over 'results'"

Hope that is what you are looking for, have fun!

In Django, the HTML is filled with data before getting served to the end client. So if you want next page data in your front-end code and that too from Django Views then you will have to go to backend again and get the data ant that will require the page to be reloaded.

If you don't want to reload the page then you will have to write APIs using Django Rest Framework. And in the front-end code just use those APIs to navigate between different pages.

Hope this helps!!

First of all in your views.py write this in your view function from which you are rendering this template

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import blog

def your_view_function(request):
    blogs = blog.objects.all()
    page = request.GET.get('page', 1)
    paginator = Paginator(blogs, 5) #number of blogs you want to paginate
    try:
        blogs = paginator.page(page)
    except PageNotAnInteger:
        blogs = paginator.page(1)
    except EmptyPage:
        blogs = paginator.page(paginator.num_pages)
    return render(request,'your_html_page.html',{'blogs':blogs}

and in your html page write this most preferred boostrap pagination

<nav aria-label="Page navigation example">
    <ul class="pagination justify-content-start mt-3">
    {% if not blogs.has_previous%}
    <li class="page-item disabled">
        <a class="page-link" href="#" tabindex="-1">Previous</a>
    </li>
    {% endif %}
    {% if blogs.has_previous%}
      <li class="page-item">
        <a class="page-link" href="?page={{blogs.previous_page_number}}" tabindex="-1">Previous</a>
      </li>
    {% endif %}
      {% if blogs.has_previous%}
      <li class="page-item"><a class="page-link" href="?page={{blogs.previous_page_number}}">{{blogs.previous_page_number}}</a></li>
      {% endif %}
      <li class="page-item"><a class="page-link" href="#">{{blogs.number}}</a></li>
      {% if blogs.has_next%}
      <li class="page-item"><a class="page-link" href="?page={{blogs.next_page_number}}">{{blogs.next_page_number}}</a></li>
      {% endif %}
      {% if blogs.has_next%}
      <li class="page-item">
        <a class="page-link" href="?page={{blogs.next_page_number}}">Next</a>
      </li>
      {% endif %}
      {% if not blogs.has_next%}
        <li class="page-item disabled">
            <a class="page-link" href="#" tabindex="-1">Next</a>
        </li>
        {% endif %}
    </ul>
  </nav>
Related