Stagger
Stagger

Reputation: 115

infinite scrolling using django

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

Answers (1)

Jay
Jay

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

Related Questions