I’ll show you how to add infinite scrolling to your Django app in 60 seconds using HTMX.
Infinite scroll speeds up your initial page load. Instead of immediately loading all content, you only load content as your users scroll.
There are 5 steps to add infinite scroll with HTMX and Django below.
Our finished Django app with infinite scrolling will look like this:
Optional video tutorial featuring me below 📽️:
Let’s go 🚀
Setup Django app
- Install our requirements into a virtual environment and create our Django project and app:
pip install django faker
django-admin startproject core .
python manage.py startapp sim
Update settings.py
INSTALLED_APPS = [
# ...
'sim',
]
1. Create the Model and Sample Data
# sim/models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
photo_url = models.URLField()
def __str__(self):
return self.title
- Run migrations:
python manage.py makemigrations
python manage.py migrate
- Generate some sample data:
python manage.py shell
# In the python shell:
from sim.models import Article
from faker import Faker
fake = Faker()
for i in range(100):
sentences = ' '.join(fake.sentences(5))
Article.objects.create(
title=fake.sentence(),
content=sentences,
photo_url=f"https://picsum.photos/seed/{i+1}/600"
)
2. Create the views
# sim/views.py
from django.core.paginator import Paginator
from django.shortcuts import render
from .models import Article
def articles(request):
"""
Fetch paginated articles and render them.
"""
page_number = request.GET.get('page', 1)
paginator = Paginator(Article.objects.all(), 10)
page_obj = paginator.get_page(page_number)
return render(request, 'articles.html', {'page_obj': page_obj})
3. Update URLs
- Update core/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('sim.urls')),
]
- Create
sim/urls.py
containing:
from django.urls import path
from . import views
urlpatterns = [
path('', views.articles, name='articles'),
]
4. Create HTML template
- Create templates folder at
sim/templates/
- Create
articles.html
insim/templates/
containing:
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/htmx.org@1.9.6" integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni" crossorigin="anonymous"></script>
<style>
/* Body and Container Styles */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
}
#articles {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
max-width: 1200px;
margin: auto;
padding: 20px;
}
h1 {
grid-column: 1 / -1; /* Span all columns */
margin-bottom: 20px;
text-align: center;
text-decoration: underline;
}
/* Article Styles */
.article {
border: 1px solid #ccc;
padding: 20px;
border-radius: 8px;
}
.article h2 {
font-size: 24px;
margin-bottom: 10px;
text-align: center;
}
.image-container {
display: flex;
justify-content: center;
}
.article img {
max-width: 100%;
height: auto;
border-radius: 8px;
}
.article p {
text-align: justify;
}
</style>
</head>
<body>
<h1>Articles</h1>
<div id="articles">
{% for article in page_obj %}
<div class="article">
<h2>{{ article.title }}</h2>
<a class="image-container" href="{{ article.photo_url }}">
<img width="300" height="300" src="{{ article.photo_url }}" alt="A sample image"/>
</a>
<p>{{ article.content }}</p>
{% if page_obj.has_next and forloop.last %}
<span hx-get="{% url 'articles' %}?page={{ page_obj.next_page_number }}"
hx-swap="beforeend" hx-target="#articles" hx-select=".article"
hx-trigger="revealed">
</span>
{% endif %}
</div>
{% endfor %}
</div>
</body>
</html>
5. Run our server
python manage.py runserver
- Visit your development server, normally at http://127.0.0.1:8000/
Finished - You can now scroll infinitely through your articles 🎉
You've just built a sleek Django app complete with infinite scrolling. You get the benefits of loading the content that the user wants on demand, meaning a much faster initial page load.
P.S - Photon Designer
I'm building Photon Designer - an entirely visual editor for building Django frontend at the speed that light hits your eyes 💡.