Auto Pagination issues in Django, how to fix?
How to resolve duplication with automatic pagination?
There’s a template home.html and home_list.html;
In home_list.html, JSON format is successfully passed, but Ajax misbehaves and creates a bunch of duplicate posts during automatic pagination; how to fix?
home.html:
<script>
$(document).ready(function(){
var nextPageUrl = '/load-posts/'; // Using URL for loading posts
function loadMorePosts() {
// Display loading element
//$('#loading').text('Loading...');
// Perform a GET request to the server
$.get(nextPageUrl, function(data) {
// Hide loading element
//$('#loading').text('Load more');
// Append HTML with posts to the end of the container
$('#post_contenter').append(data.posts_html);
// Update URL for the next page
nextPageUrl = data.next_page_url;
}).fail(function() {
// Handle request error if it occurs
console.error('Error loading posts');
// Hide loading element
$('#loading').hide();
});
}
// Event handler for page scroll
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() >= $(document).height()) {
// Call the function to load additional posts
loadMorePosts();
}
});
// Initialize loading of the first page of posts when the page is loaded
loadMorePosts();
});
</script>
views.py:
from django.shortcuts import render, redirect
from usercreatepost.forms import PostForm
from publication.models import Userpublication
from user.models import Profile****, Subscription
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.urls import reverse
from django.http import JsonResponse
from django.template.loader import render_to_string
from django.db.models import Q
@login_required
def create_post(request):
form = PostForm(request.POST or None)
# If request is POST, save the form
if request.method == 'POST':
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('home')
# Get IDs of users subscribed by the current user
subscribed_user_ids = Subscription.objects.filter(subscriber=request.user).values_list('target_user', flat=True)
# Get all posts from authors subscribed by the current user
subscribed_posts = Userpublication.objects.filter(author__in=subscribed_user_ids)
# Get all posts from the current user
own_posts = Userpublication.objects.filter(author=request.user)
# Merge post lists
all_posts = (subscribed_posts | own_posts).order_by('-time_create')
# Get the page posts object for display
page_posts = all_posts
context = {'form': form, 'post_lists': page_posts, 'title': '**** | News'}
return render(request, '****/home.html', context)
def load_posts(request):
# Get page number from the request
page_number = request.GET.get('page', 1) # Set default value to 1
# Get IDs of users subscribed by the current user
subscribed_user_ids = Subscription.objects.filter(subscriber=request.user).values_list('target_user', flat=True)
# Get all posts subscribed by the current user or authored by them
all_posts = Userpublication.objects.filter(Q(author__in=subscribed_user_ids) | Q(author=request.user))
# Create Paginator object
paginator = Paginator(all_posts, 10) # 10 posts per page
try:
# Get objects for the current page
current_page_posts = paginator.page(page_number)
except PageNotAnInteger:
# If page number is not an integer, show first page
current_page_posts = paginator.page(1)
except EmptyPage:
# If page number is out of range, return empty response
return JsonResponse({'posts_html': '', 'next_page_url': None})
# Render HTML with posts for the current page
posts_html = render_to_string('****/home_list.html', {'posts': current_page_posts})
# Get URL for the next page if it exists
next_page_url = None
if current_page_posts.has_next():
next_page_url = f"{reverse('load_posts')}?page={current_page_posts.next_page_number()}"
# Return JSON response with HTML and URL for the next page
return JsonResponse({'posts_html': posts_html, 'next_page_url': next_page_url})