As the “next page” button becomes a thing of the past, we look for new ways to provide streaming information. Enter infinite scroll. Implementing infinite scroll in Django is easy thanks to the built-in paginator.

What you need is a view that will generate additional results of an object when called upon via AJAX. Assume this model in a “people” application:

class Person(models.Model):
    name = models.CharField()
    age = models.IntegerField()

Build this view to generate the list page and handle AJAX calls for more results:

from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.shortcuts import render

from people.models import Person

def people_list(request):
    # If this isn't AJAX, just return the page
    if not request.is_ajax():
        return render(request, 'people/people_list.html')

    people_qs = Person.objects.all().order_by('name')

    # Get the paginator
    paginator = Paginator(people, 5)
    try:
        page = int(request.GET.get('page', 1))
    except ValueError:
        page = 1
    try:
        people = paginator.page(page)
    except (EmptyPage, InvalidPage):
        people = paginator.page(paginator.num_pages)

    # Return a snippet
    context = {
        'people': people,
        'paginator': paginator,
    }
    return render(request, 'people/_people_list.html', context)

The snippet is fairly simple. _people_list.html:

{% for person in people %}
<li{% if people.has_next %} data-next="{{ people.next_page_number }}"{% endif %}>
    <p>Name: {{ person.name }}</p>
    <p>Age: {{ person.age }}</p>
</li>
{% endfor %}

And in in the main page, we enable the whole thing with JavaScript. people_list.html:

<ul id="people"></ul>

<script>
function load_people(page) {
    var url = "{% url people-list %}";
    if (page) {
        url += '?page=' + page;
    }
    $.get(
        url,
        function(response) {
            $('ul#people').append(response);
        }
    );
}

$(document).ready(function() {
    load_people();  // Get initial set
    $(window).scroll(function() {
        var break_point = $(document).height() - ($(window).height() * 1.02);
        if (($window).scrollTop() >= break_point) {
            var next_page = $('ul#people li:last').attr('data-next');
            if (next_page) {
                load_people(next_page);
            }
        }
    });
});
</script>

And there you have it. Alternate jQuery infinite scroll techniques can be found here.