DEV Community

Cover image for Infinite scroll with Django

Posted on • Updated on

Infinite scroll with Django

By Reverse Python

Hey DEV Network!

Today I am going to show you quick tutorial about how to create endless pagination or infinite scroll with Django

There are many sources on internet related with this topic but majority of them are not fully explained. So, I will try to explain it clearly and step by step for you.

Alright! Let's launch our infinite-scroll-django rocket!

I am assuming that you already created your project

Step 1: Creating our model

We are going to create very simple blog with posts. Let's create our post model in

   from django.db import model

   class Post(models.Model):
     title = models.CharField(max_length=250)
     description = models.TextField()
     image = models.FileField(null=True, blank=True)

     def __str__(self):
         return self.title

Enter fullscreen mode Exit fullscreen mode

Don't forget to migrate your model :)

Step 2: Creating our view

In we are going to import ListView, it is a class-based view and it will contain the list of objects.

  from django.shortcuts import render
  from .models import Post
  from django.views.generic.list import ListView

  class PostsView(ListView):
      model = Post 
      paginate_by = 2
      context_object_name = 'posts'
      template_name = 'posts.html'
      ordering = ['title']
Enter fullscreen mode Exit fullscreen mode

As you see I will load 2 posts per scroll by using paginate_by attribute but you can change it how many you want. The context_object_name attribute specifies the name of variable to access from templates. Providing a useful context_object_name is always a good idea. Your coworkers who design templates will thank you. In addition, you can order posts by title or published date but for now let's keep it title.

Step 3: URL Configuration

Time to configure our, so let's see the code first.

  from django.contrib import admin
  from django.urls import path

  from posts.views import PostsView
  from django.conf import settings 
  from django.conf.urls.static import static 

  urlpatterns = [
      path('', PostsView.as_view(),  name="posts"),
  ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Enter fullscreen mode Exit fullscreen mode

In class-based views, you have to call as_view() function so as to return a callable view that takes a request and returns a response. Its the main entry-point in request-response cycle in case of generic views.

Just reminder static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) is for serving media files.

Step 4: Waypoints JS and Template

Waypoints is a small jQuery plugin that makes it easy to execute a function whenever you scroll to an element.

Documentation of Waypoints

Alright! Let's see the code first

            <div class="container">
                <div class="row infinite-container">
                    {% for post in posts %}
                        <div class="col-md-6 infinite-item">
                            <div class="card mb-4 shadow-sm">
                                <img class="img-thumbnail"  src="{{post.image.url}}"/>
                                <div class="card-body">
                                    <p class="card-text">
                    {% endfor %}
                {% if page_obj.has_next %}
                <a class="infinite-more-link" href="?page={{ page_obj.next_page_number }}"></a>
                {% endif %}
                <div class="d-flex justify-content-center" style="display:none;">
                    <div class="spinner-border" role="status">
                        <span class="sr-only">Loading...</span>

    <script src="/static/js/jquery-2.2.4.min.js"></script>
    <script src="/static/js/jquery.waypoints.min.js"></script>
    <script src="/static/js/infinite.min.js"></script>
    var infinite = new Waypoint.Infinite({
        element: $('.infinite-container')[0],
        handler: function(direction) {

    offset: 'bottom-in-view',

    onBeforePageLoad: function () {
    onAfterPageLoad: function () {



Enter fullscreen mode Exit fullscreen mode

This is the main part of tutorial, we are first including jquery-2.2.4.min.js. It is better to include 2.2.4 version of jQuery otherwise it will cause errors. Then add jquery.waypoints.min.js and infinite.min.js

You can get scripts from directly github repo of waypoints.


element option for Infinite referes to the container around all infinite items that will be used as the waypoint and fetched items will be appended to.

.infinite-more-link is matching the "Next Page" element on every page.

.infinite-item is a selector string that should match the individual items that will be pulled out of each page and appended to the item container.

offset is the same offset option from a regular Waypoint, except the default is now 'bottom-in-view' instead of 0. This means, by default, new items will be loaded when the bottom of the container comes into view.

PageLoad functions is for display spinner while posts are loading

Mission Accomplished!

Infinite Scroll Project

You just learned something very useful today and launched your infinite-scroll-django rocket! You can clone or download this project from my git repository and don't forget to follow me on social media, join Reverse Astronauts community!

Stay Connected!


Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.

Top comments (6)

zodman profile image
Andres 🐍 in πŸ‡¨πŸ‡¦

Take a look how intercoolerjs do the same on example section

thepylot profile image

sure I will Thanks! :)

quetzacuatl profile image

after two days of trying to make this infinite scrolling work I came across your tutorial. Thanks my friend

viveklele0 profile image
Vivek • Edited

can you help me It's not working for me I have been working on this for 1 week

viveklele0 profile image

Somebody Please can help me it's not working

jacobfisher123 profile image

Really useful information