Reputation: 115
I am fairly new to web development and I am building a blog style website. I use pagination to split posts into seperate pages but now i want to rather go for infinite scrolling like facebook does.
I have watched countless videos and read a whole bunch of docs regarding this but to be honost, I get lost in all of them.
I use django and python for my backend and all sources seem to use other languages etc like JS and ajax etc.
All these mentioned sources start from the ground up which somehow confuses me as i already have pagination in place.
Is there a way i can just tweak my current pagination to enable infinite scrolling instead of rebuilding the whole thing in different languages? or just help me get this done the right way. I've been struggling with this for weeks now so now i come here as a last resort.
No point in running straight here if no effort was put in before hand
Here is my current pagination code:
views.py:
from django.shortcuts import render, get_object_or_404
from .models import Post
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
class PostListView(ListView):
model=Post
template_name = "Fire_Ant/home.html"
context_object_name = "posts"
paginate_by = 4
ordering = ["-date_posted"]
class UserPostListView(ListView):
model=Post
template_name = "Fire_Ant/user_posts.html"
context_object_name = "posts"
rdering = ["-date_posted"]
paginate_by = 4
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get("username"))
return Post.objects.filter(author=user).order_by("-date_posted")
class PostDetailView(DetailView):
model=Post
class PostCreateView(LoginRequiredMixin, CreateView):
model=Post
fields = ["title", "content"]
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model=Post
fields = ["title", "content"]
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model=Post
success_url = "/"
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
def about(request):
return render(request,"Fire_Ant/about.html", {"title": "about"})
def home(request):
numbers_list = range(1, 1000)
page = request.GET.get('page', 1)
paginator = Paginator(numbers_list, 20)
try:
numbers = paginator.page(page)
except PageNotAnInteger:
numbers = paginator.page(1)
except EmptyPage:
numbers = paginator.page(paginator.num_pages)
return render(request, 'blog/home.html', {'numbers': numbers})
home.html:
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% elif num > page_obj.number|add:"-3" and num < page_obj.number|add:"3" %}
<a class="btn btn-outline-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages}}">Last</a>
{% endif %}
{% endif %}
Upvotes: 1
Views: 2720
Reputation: 1309
In the code below, 20 is interchangeable with however many objects you want shown per each scroll to the bottom of the page.
views.py
def callajax(request):
if request.method == 'POST':
response_json = request.POST
response_json = json.dumps(response_json)
data = json.loads(response_json)
counter = int(data['counter'])
obj = Post.objects.all()[counter:][:20]
data = serializers.serialize('json', obj)
data = {'data':data'}
return JsonResponse(data, safe=False)
js
let counter = 0
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
function seemore(){
var counter = counter+20;
counter = counter+20;
info = {'counter': counter, 'csrfmiddlewaretoken':"{{ csrf_token }}"}
$.ajax({
type: "POST",
url: '{% url "callajax" %}',
data:info,
datatype:'json',
headers: { "X-CSRFToken": '{{csrf_token}}' },
success: function(data){
#here you add the html to the dom that you want shown once you get to bottom of page.
}
}
})
Upvotes: 3