Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why paginating a ListView in django does not work?

I am doing the CS50W, the Network project, when I want to move to next / go back to the pagination of my web. Nothing happened. I tried to debug the view.py file, anytime I click the next or previous button in script.js , it all returned page_number as none in views.py . I have no idea why this happened. Can you guys help me?

Here are the code in my views.py :

def index(request):
    return render(request, "network/index.html")

def allPosts(request):
    # Get all posts data - json
    allPosts = Post.objects.all()
    # Return emails in reverse chronologial order
    allPosts = allPosts.order_by("-timestamp").all()
    # Show 2 contacts per page.
    paginator = Paginator(allPosts, 2) 
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    # return json all posts
    data = {
        'posts': [post.serialize() for post in page_obj],
        'page': {
            'has_previous': page_obj.has_previous(),
            'previous_page': page_obj.has_previous() and page_obj.previous_page_number() or None,
            'has_next': page_obj.has_next(),
            'next_page': page_obj.has_next() and page_obj.next_page_number() or None,
            'num_pages' : page_obj.paginator.num_pages,
            'current_page' : page_number
        }
    }
    return JsonResponse(data, safe=False)

Code in my script.js file:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

document.addEventListener('DOMContentLoaded', function() {
    // Use buttons to toggle between views
    document.querySelector('.showallPosts').addEventListener('click',showallPosts);
    showallPosts();
  });

  function showallPosts(){
    // Clear out composition field
    document.querySelector('#allPosts-view').value = '';
    // Show the mailbox name
    document.querySelector('#allPosts-view').innerHTML = `
        <h3>All Posts</h3>
    `;
    // Get data
    fetch(`/allPosts`)
    .then(response => response.json())
    .then(result => {
      //Process to get data
      for(let i = 0; i < result.posts.length; i++) {
        const newDiv = document.createElement('div');
        newDiv.classList.add('list-group-item');
        let post = result.posts[i];
        let post_timestamp = post.timestamp;
        let post_author = post.author;
        let post_content = post.content;
        let post_likes = post.likes;
        newDiv.innerHTML = `
          <h5>Author: ${post_author}</h5>
          <h6>At: ${post_timestamp}</h6>
          <p>Has wrote: ${post_content}</p>
          <p><strong>Likes</strong>: ${post_likes}</p>
        `;
        document.querySelector('#allPosts-view').append(newDiv);
      }
      page = result.page;
      const toggleDiv = document.createElement('div');
      toggleDiv.classList.add('pagination');
      if (page.has_previous) {
        toggleDiv.innerHTML = `
            <a href="?page=1">&laquo; first</a>
            <a href="?page=${page.previous_page}">previous</a>
        `;
      }
      if (page.has_next) {
        toggleDiv.innerHTML += `
          <a href="?page=${page.next_page}">next</a>
          <a href="?page=${page.num_pages}">last &raquo;</a>
        `;
      }
      document.querySelector('#toggle').append(toggleDiv);
    })
  }

My urls.py file:


from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name="index"),
    path("login", views.login_view, name="login"),
    path("logout", views.logout_view, name="logout"),
    path("register", views.register, name="register"),
    path("createPost", views.createPost, name="createPost"),
    path("allPosts", views.allPosts, name="allPosts")
]

I expect the page to display other posts, but no. It is always the first page of the pagination.

>Solution :

You always fetch without a page parameter. Indeed:

fetch(`/allPosts`)

You don’t add a ?page= parameter, so it will always fetch data of the first page.

You should look for a ?page= parameter in the page, and add this to the fetch request, like:

const searchParams = new URLSearchParams(window.location.search);
fetch(`/allPosts` + new URLSearchParams({
    page: searchParams.get('page') || 1
}))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading