Lazy pagination for Django with optional infinite-scroll JavaScript
Project description
Django Endless Pagination
Lazy pagination for Django with an optional, dependency-free JavaScript helper that loads the next page on click or while scrolling.
The package ships:
- the
{% lazy_paginate %}and{% show_more %}template tags; - a
LazyPaginatorthat avoidsCOUNT(*)queries by overshooting by one row; - a small vanilla-JS module (
endless-pagination.js) exposingendlessPaginate({ paginateOnScroll, paginateOnScrollMargin }).
The package is available on pypi.org:
uv add webstack-django-endless-pagination
Setup
Add 'endless_pagination' to INSTALLED_APPS. The
django.template.context_processors.request context processor must be
enabled (it is in Django's default project template).
Quickstart
{% load endless %}
{% lazy_paginate 10 entries %}
{% for entry in entries %}
{# render the entry #}
{% endfor %}
{% show_more %}
Load the next page over Ajax (with optional infinite scroll):
{% load static %}
<script src="{% static 'endless_pagination/js/endless-pagination.js' %}"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
endlessPaginate({ paginateOnScroll: true });
});
</script>
The view must return the page partial when the request carries the
querystring key (defaults to page), and the full page otherwise:
from django.shortcuts import render
from endless_pagination.settings import PAGE_LABEL
def entries(request):
template = "entries/page.html" if PAGE_LABEL in request.GET else "entries/index.html"
return render(request, template, {"entries": Entry.objects.all()})
Template tags
Both tags live in the endless library: {% load endless %}.
lazy_paginate
Paginates objects without issuing a COUNT(*) query.
{% lazy_paginate entries %} {# uses ENDLESS_PAGINATION_PER_PAGE #}
{% lazy_paginate 20 entries %} {# 20 per page #}
{% lazy_paginate 5,40 entries %} {# 5 on the first page, 40 thereafter #}
After the call, entries in the template context is the slice for the
current page. Must be used before {% show_more %}.
show_more
Renders the link that loads the next page over Ajax. Call it after
{% lazy_paginate %}.
{% show_more %} {# default label and loading text #}
{% show_more "Encore" %} {# custom label #}
{% show_more "Encore" "Chargement…" %} {# custom label + loading text #}
{% show_more "Encore" "Chargement…" "btn" %} {# extra CSS class on the link #}
You can override the default endless/show_more.html template, but the
JavaScript helper expects:
- the
a.endless_morelink inside an.endless_containerelement; - the link's
relattribute to start with the querystring key; - a hidden
.endless_loadingelement next to the link, shown while the next page is being fetched.
JavaScript
The bundled endless-pagination.js is dependency-free. It exposes two
globals:
endlessPaginate(options)— convenience initialiser bound todocument.body.EndlessPagination— the underlying class, useful when scoping to a specific element.
endlessPaginate({ paginateOnScroll: true, paginateOnScrollMargin: 20 });
const widget = new EndlessPagination(
document.querySelector('#entries'),
{ paginateOnScroll: true }
);
widget.destroy(); // detach click and scroll listeners
Options
| Option | Default | Description |
|---|---|---|
containerSelector |
'.endless_container' |
Wrapper around the show more link. |
loadingSelector |
'.endless_loading' |
Loader element shown while fetching. |
moreSelector |
'a.endless_more' |
Link that loads the next page. |
paginateOnScroll |
false |
Trigger the next page from scroll. |
paginateOnScrollMargin |
1 |
Bottom margin in pixels for the trigger. |
Settings
| Setting | Default | Description |
|---|---|---|
ENDLESS_PAGINATION_PER_PAGE |
10 |
Default page size; overridable in the tag. |
ENDLESS_PAGINATION_PAGE_LABEL |
'page' |
Querystring key carrying the page number. |
ENDLESS_PAGINATION_ORPHANS |
0 |
Same meaning as Django's Paginator(orphans=…). |
ENDLESS_PAGINATION_LOADING |
'loading' |
HTML-safe markup shown by the loader element. |
Development
Install dev dependencies:
uv sync
Run the test suite:
cd src/tests
uv run python manage.py test endless_pagination
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file webstack_django_endless_pagination-4.0.1.tar.gz.
File metadata
- Download URL: webstack_django_endless_pagination-4.0.1.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c8afa95bdd19d9ea07ddd6a3b146c9adc9e2c0970db89964d7bfd8c60d60c35
|
|
| MD5 |
cde30cfc229b6f1fac876936d03c4a3c
|
|
| BLAKE2b-256 |
a40f72ac3cffb62b8ded077181d1a7af8eba96c4410e3284d266179df5ec4b0c
|
File details
Details for the file webstack_django_endless_pagination-4.0.1-py3-none-any.whl.
File metadata
- Download URL: webstack_django_endless_pagination-4.0.1-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52ac4aa1c627ca42cd5d0d189ec554e5d7de7dbc65bc55b3538ef65d60725745
|
|
| MD5 |
29d5c8cfa66836cd58e4ce7265daf752
|
|
| BLAKE2b-256 |
854ab7bb0be114835e6daaf1721a261fd99c258c8feb05492c42054bdffccad4
|