Hello, I will take you straight through the process of adding inifinte pagination in your django application like it's abc complete code is down below
Note: this is for absolute beginner
First thing first, we create our django project.
mkdir django-infinite-scroll
cd django-infinite-scroll
pipenv shell #this initializes with Pipfile and creates the environment
We install our django application
pipenv install django
We create a new django project
django-admin startproject core .
We create our app blog and add it to INSTALLED_APPS
.
python manage.py startapp blog
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# our blog app
'blog.apps.BlogConfig',
]
Run the development server and make sure everything is working properly.
python manage.py runserver
Migrate the database and createsuperuser in my case the credentials were username: admin
password: admin
run the server and let the fun begin!
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
Creating a simple model for a blog to hold
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
published = models.BooleanField(default=False)
def __str__(self):
return self.title
# views.py
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render
from .models import Post
def posts(request):
# it's not a bug if it's intentional ;)
post_list = Post.objects.filter(published=False)
# we get page 1 returns 10 post objects
paginator = Paginator(post_list, 10)
# page_number is initialized to `1` see main.js
page_number = request.GET.get('page')
# we are applying page number which defaults to `1`
page_obj = paginator.get_page(page_number)
if page_number:
# We are checking if `page_number` < or ==
paginator.num_pages total amount of pages returned by the `Paginator` this only runs if the above conditions are met
if int(page_number) <= paginator.num_pages:
obj_list = paginator.get_page(page_number)
obj_list = obj_list.object_list.values()
return JsonResponse(list(obj_list), status=200, safe=False)
ctx = {'page_obj': page_obj}
return render(request, 'post/posts.html', ctx)
Add your app url to project url config
#core/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls'))
]
Define your app urls.py
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.posts, name="posts")
]
We create a simple example template
# template
# 'blog/templates/post/posts.html'
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#content{
margin: 0 auto;
width: 40vw;
}
</style>
</head>
<body>
<div id="content">
{% for post in page_obj %}
<div>
<h1>{{post.title}}</h1>
<p>{{post.content}}</p>
</div>
{% endfor %}
</div>
</body>
<script type="text/javascript" src="{% static 'blog/js/main.js' %}"></script>
</html>
On the js side of things, we are listening to scroll event, when we scroll to the bottom of the page, we trigger a function that calls our view which in turn returns a Json objects that we can inject to our template.
# main.js
# 'blog/static/blog/js/main.js'
content = document.querySelector("#content");
let page = 1
window.onscroll = function() {
url = `/?page=${page}`
if (window.innerHeight + window.pageYOffset >= document.body.offsetHeight) {
fetch(url).then(res => {
if (res.ok) {
return res.json();
}
}).then(data => {
console.dir(data)
page += 1
content.innerHTML += data.map(
obj=>`<div>
<h1>${obj.title}</h1>
<p>${obj.content}</p>
</div>`
).join("\n")
}).catch(err => {
})
}
}
I hope this helps shed some weight on your web application, because things like these are not worth intsalling an external library (waypointjs i'm looking at you), please help your app shed some weight! Happy coding!
Top comments (2)
is it possible to invert this
Please explain what you meant by invert.