Last active
November 27, 2023 10:01
-
-
Save nicholaskajoh/ae85bb836f2a6254244c847b962095d4 to your computer and use it in GitHub Desktop.
Lazy load your content with Django and jQuery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script type="text/javascript"> | |
// A CSRF token is required when making post requests in Django | |
// To be used for making AJAX requests in script.js | |
window.CSRF_TOKEN = "{{ csrf_token }}"; | |
</script> | |
</head> | |
<body> | |
<h2>My Blog Posts</h2> | |
<div id="posts"> | |
{% include 'myapp/posts.html' %} | |
</div> | |
<div><a id="lazyLoadLink" href="javascript:void(0);" data-page="2">Load More Posts</a></div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import unicode_literals | |
from django.db import models | |
class Post(models.Model): | |
title = models.CharField() | |
content = models.TextField() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% for post in posts %} | |
<div> | |
<h4>{{ post.title }}</h4> | |
<p>{{ post.content }}</p> | |
</div> | |
{% endfor %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
$('#lazyLoadLink').on('click', function() { | |
var link = $(this); | |
var page = link.data('page'); | |
$.ajax({ | |
type: 'post', | |
url: '/lazy_load_posts/', | |
data: { | |
'page': page, | |
'csrfmiddlewaretoken': window.CSRF_TOKEN // from index.html | |
}, | |
success: function(data) { | |
// if there are still more pages to load, | |
// add 1 to the "Load More Posts" link's page data attribute | |
// else hide the link | |
if (data.has_next) { | |
link.data('page', page+1); | |
} else { | |
link.hide(); | |
} | |
// append html to the posts div | |
$('#posts').append(data.posts_html); | |
}, | |
error: function(xhr, status, error) { | |
// shit happens friends! | |
} | |
}); | |
}); | |
}(jQuery)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from myapp import views | |
urlpatterns = [ | |
url(r'^$', views.index, name='index'), | |
url(r'^lazy_load_posts/$', views.lazy_load_posts, name='lazy_load_posts'), | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.shortcuts import render | |
from myapp.models import Post | |
from django.template import loader | |
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger | |
from django.http import JsonResponse | |
def index(request): | |
posts = Post.objects.all()[:5] | |
return render(request, 'myapp/index.html', {'posts': posts}) | |
def lazy_load_posts(request): | |
page = request.POST.get('page') | |
posts = Post.objects.all() | |
# use Django's pagination | |
# https://docs.djangoproject.com/en/dev/topics/pagination/ | |
results_per_page = 5 | |
paginator = Paginator(posts, results_per_page) | |
try: | |
posts = paginator.page(page) | |
except PageNotAnInteger: | |
posts = paginator.page(2) | |
except EmptyPage: | |
posts = paginator.page(paginator.num_pages) | |
# build a html posts list with the paginated posts | |
posts_html = loader.render_to_string('myapp/posts.html', {'posts': posts}) | |
# package output data and return it as a JSON object | |
output_data = {'posts_html': posts_html, 'has_next': posts.has_next()} | |
return JsonResponse(output_data) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I also added:
before line 27 views.py
and change line 27 to:
posts_html = loader.render_to_string('myapp/posts.html', {'user': user, 'posts': posts})
because we must have user info in template
example: