Skip to content

Instantly share code, notes, and snippets.

@63phc
Last active December 26, 2017 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 63phc/d3623c46bb9141785bddb806f6a1a009 to your computer and use it in GitHub Desktop.
Save 63phc/d3623c46bb9141785bddb806f6a1a009 to your computer and use it in GitHub Desktop.
ajax paginator
## index.html
<html>
<head>
<script type="text/javascript">
// needed when making post requests in Django
// we'll use this for the ajax request 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>
## models.py
from __future__ import unicode_literals
from django.db import models
class Post(models.Model):
# Gonna pass on this one. You know what to do...
# https://docs.djangoproject.com/en/dev/topics/db/models/
pass
## posts.html
{% for post in posts %}
<div>
<h4>{{ post.title }}</h4>
<p>{{ post.content }}</p>
</div>
{% endfor %}
## script.js
(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
$('#div').append(data.posts_html);
},
error: function(xhr, status, error) {
// shit happens friends!
}
});
});
}(jQuery));
## urls.py
from myapp import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^lazy_load_posts/$', views.lazy_load_posts, name='lazy_load_posts'),
]
## views.py
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()[:5] # get just 5 posts
# 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