I need help solving a problem with automatic pagination. When automatic pagination occurs from the home_list.html template to the home.html template, all functions of the template stop working, even though the template itself is paginated correctly. The functionality stops working after pagination, namely: "edit" and "delete" the published post, "Add comment", "Edit comment", "Save edited comment", "Delete comment".In the home.html template, these functions work in the {% for post in post_lists %} loop, but after automatic pagination from the home_list.html template in the {% for post in posts %} loop, these functions do not work. How can I fix this?
home.html
<div id="post_contenter">{% for post in post_lists %}<div class="post_content" id="post_content"> <!-- Add identifier post_content --><div class="post_header"><div class="post_user_avatar"> {% if post.author.avatar %}<img style="width:50px; height: 50px;" src="{{ post.author.avatar.url }}" class="user-picture-small"> {% else %}<img style="width:50px; height: 50px;" src="{% static 'twippie/img/avatar.png' %}" class="card_user_picture_small"> {% endif %}</div><div class="post_user_info"><div class="post_user_fullname"><a href="{% url 'user:profile_username' post.author.username %}" class="post_user_fullname_style">{{ post.author.first_name }} {{ post.author.last_name }}</a></div><div class="post_user_username"><a href="{{ user_profile.username }}" class="post_user_nickname_style">@{{ post.author }}</a> {% if post.author.verification %}<span class="verified_user_small"></span> {% endif %}</div><div class="post_user_date"><a href="{{ post.get_absolute_url }}" class="post_user_date_style">{{ post.time_create }} {{ post.time_create|naturaltime }}</a></div></div></div><div class="post_user_more"><div class="dropdown dropbtn" style="float:right;"><div class="dropdown-content"> {% if request.user == post.author %}<span><a href="{% url 'edit_post' post_slug=post.slug %}" class="post_user_edit">Edit</a></span> {% endif %} {% if user.is_authenticated and user == post.author %}<span><a href="{% url 'delete_post' post_slug=post.slug %}" class="post_user_delete">Delete post</a></span> {% endif %}<span><a href="" class="post_user_complain">Report</a></span></div></div></div><div class="post_user_content"> {{ post.content }}</div><div class="post_user_action"><div class="post_user_liked_post">{% if liked_by_current_user %}<div class="unlike-button" id="unlike-button-{{ post.id }}" data-post-id="{{ post.id }}"></div>{% else %}<div class="like-button" id="like-button-{{ post.id }}" data-post-id="{{ post.id }}"></div>{% endif %}<div class="count_likevalue"><span class="like-count-value like_count_style" id="like-count-{{ post.id }}" data-post-id="{{ post.id }}">{{ like_count }}</span></div></div><div class="containercomment_post"><!-- Unique identifier for each post --><div class="post_user_comment_post" data-post-id="{{ post.id }}"><span class="count_comment">{{ post.comments.count }}</span></div></div><div class="post_user_share_post"></div><div class="post_user_views_post"><div class="post_user_views_post_count"><span class="post_user_views_post_count_style">125025</span></div></div></div><!-- Unique identifier for each comment form --><div class="comment-form hidden" data-post-id="{{ post.id }}"><hr><form action="{% url 'add_comment' post_id=post.id %}" method="post"> {% csrf_token %}<textarea name="content" class="user_comment_style" placeholder="Write a comment..." required></textarea><button type="submit" class="img_sbmt"></button></form></div><!-- Display all comments -->{% for comment in post.comments.all %}<div class="comment-container"><div class="comment_post"> {% if comment.author.avatar %}<img src="{{ comment.author.avatar.url }}" class="comment_author_img_style"> {% else %}<img src="{% static 'twippie/img/avatar.png' %}" class="comment_author_img_style"> {% endif %}<div class="comment_author"><a href="{% url 'user:profile_username' username=comment.author.username %}">{{ comment.author.first_name }}</a></div><div class="comment_content" id="comment-content-{{ comment.id }}">{{ comment.content }}</div><div class="comment_time">{{ comment.created_at }}<!--<span class="answer_comment_user"><a>Reply</a></span>-->{% if comment.author == request.user %}<span id="edit-actions-{{ comment.id }}" class="edit_comment_user"><a href="#" onclick="editComment({{ comment.id }})" class="edit_comment_link">edit</a><a href="#" onclick="saveComment(event, {{ comment.id }})" class="save_comment_link" style="display: none;">Save changes</a></span><span class="delete_comment_user"><a href="{% url 'delete_comment' comment_id=comment.id %}">delete</a></span>{% endif %}</div></div> {% if not forloop.last %}<!-- If the current comment is not the last one, add a separator --><hr class="solid_bottom"> {% endif %}<span class="massage_save_comment_error"></span> <!-- Error message --><span id="save-message-{{ comment.id }}" class="massage_save_comment"></span> <!-- Save message --></div>{% endfor %}<br></div>{% endfor %}<div id="pagination-loader" class="pagination_pages" data-page="1"></div></div><script>$(document).ready(function(){ var loadedPage = 1; // Variable to store the loaded page number // Function to load the next batch of posts function loadNextPage() { // Perform an AJAX request to the server var nextPageUrl = '/load-posts/?page='+ (loadedPage + 1); console.log("Next page URL:", nextPageUrl); $.ajax({ url: nextPageUrl, type: 'GET', dataType: 'json', success: function(response) { console.log("Response from server:", response); // Check if there is data about posts in the JSON response if (response.posts) { // Add HTML with posts to the end of the container $('#post_contenter').append(response.html_posts); // Check if there are more posts on the next page if (response.next_page_url) { // Increase the value of the loadedPage variable loadedPage++; } else { // If there is no next page, hide the loading indicator $('#pagination-loader').hide(); } } else { // If there is no data about posts, display an error message console.error('Error loading posts: data about posts is missing in the JSON response'); } }, error: function(jqXHR, textStatus, errorThrown) { // Handle the error if it occurred during the request console.error('Error loading posts:', textStatus, errorThrown); } }); } // Event handler for scrolling the page $(window).on('scroll', function() { // Get the current scroll position var scrollPosition = $(window).scrollTop(); // Get the height of the browser window var windowHeight = $(window).height(); // Get the height of the entire document var documentHeight = $(document).height(); // If the user has scrolled to the end of the page if (scrollPosition + windowHeight >= documentHeight) { // Check if the loading indicator is visible if ($('#pagination-loader').is(':visible')) { // Load the next batch of posts loadNextPage(); } } }); // Check if the first page of posts needs to be loaded when the page is loaded if($(window).scrollTop() + $(window).height() == $(document).height()) { loadNextPage(); }});</script><style> .hidden { display: none; }</style>home_list.html:
{% load humanize %}{% load static %}{% block content %}{% if posts %}<div class="post-list"> {% for post in posts %} {% if not forloop.first and post.author != request.user %}<div class="post_content" id="post_content"> <!-- Add identifier post_content --><div class="post_header"><div class="post_user_avatar"> {% if post.author.avatar %}<img style="width:50px; height: 50px;" src="{{ post.author.avatar.url }}" class="user-picture-small"> {% else %}<img style="width:50px; height: 50px;" src="{% static 'twippie/img/avatar.png' %}" class="card_user_picture_small"> {% endif %}</div><div class="post_user_info"><div class="post_user_fullname"><a href="{% url 'user:profile_username' post.author.username %}" class="post_user_fullname_style">{{ post.author.first_name }} {{ post.author.last_name }}</a></div><div class="post_user_username"><a href="{{ user_profile.username }}" class="post_user_nickname_style">@{{ post.author }}</a> {% if post.author.verification %}<span class="verified_user_small"></span> {% endif %}</div><div class="post_user_date"><a href="{{ post.get_absolute_url }}" class="post_user_date_style">{{ post.time_create }} {{ post.time_create|naturaltime }}</a></div></div></div><div class="post_user_more"><div class="dropdown dropbtn" style="float:right;"><div class="dropdown-content"> {% if request.user == post.author %}<span><a href="{% url 'edit_post' post_slug=post.slug %}" class="post_user_edit">Edit</a></span> {% endif %} {% if user.is_authenticated and user == post.author %}<span><a href="{% url 'delete_post' post_slug=post.slug %}" class="post_user_delete">Delete post</a></span> {% endif %}<span><a href="" class="post_user_complain">Report</a></span></div></div></div><div class="post_user_content"> {{ post.content }}</div><div class="post_user_action"><div class="post_user_liked_post">{% if liked_by_current_user %}<div class="unlike-button" id="unlike-button-{{ post.id }}" data-post-id="{{ post.id }}"></div>{% else %}<div class="like-button" id="like-button-{{ post.id }}" data-post-id="{{ post.id }}"></div>{% endif %}<div class="count_likevalue"><span class="like-count-value like_count_style" id="like-count-{{ post.id }}" data-post-id="{{ post.id }}">{{ like_count }}</span></div></div><div class="containercomment_post"><!-- Unique identifier for each post --><div class="post_user_comment_post" data-post-id="{{ post.id }}"><span class="count_comment">{{ post.comments.count }}</span></div></div><div class="post_user_share_post"></div><div class="post_user_views_post"><div class="post_user_views_post_count"><span class="post_user_views_post_count_style">125025</span></div></div></div><!-- Unique identifier for each comment form --><div class="comment-form hidden" data-post-id="{{ post.id }}"><hr><form action="{% url 'add_comment' post_id=post.id %}" method="post"> {% csrf_token %}<textarea name="content" class="user_comment_style" placeholder="Write a comment..." required></textarea><button type="submit" class="img_sbmt"></button></form></div><!-- Display all comments -->{% for comment in post.comments.all %}<div class="comment-container"><div class="comment_post"> {% if comment.author.avatar %}<img src="{{ comment.author.avatar.url }}" class="comment_author_img_style"> {% else %}<img src="{% static 'twippie/img/avatar.png' %}" class="comment_author_img_style"> {% endif %}<div class="comment_author"><a href="{% url 'user:profile_username' username=comment.author.username %}">{{ comment.author.first_name }}</a></div><div class="comment_content" id="comment-content-{{ comment.id }}">{{ comment.content }}</div><div class="comment_time">{{ comment.created_at }}<!--<span class="answer_comment_user"><a>Reply</a></span>-->{% if comment.author == request.user %}<span id="edit-actions-{{ comment.id }}" class="edit_comment_user"><a href="#" onclick="editComment({{ comment.id }})" class="edit_comment_link">edit</a><a href="#" onclick="saveComment(event, {{ comment.id }})" class="save_comment_link" style="display: none;">Save changes</a></span><span class="delete_comment_user"><a href="{% url 'delete_comment' comment_id=comment.id %}">delete</a></span>{% endif %}</div></div> {% if not forloop.last %}<!-- If the current comment is not the last one, add a separator --><hr class="solid_bottom"> {% endif %}<span class="massage_save_comment_error"></span> <!-- Error message --><span id="save-message-{{ comment.id }}" class="massage_save_comment"></span> <!-- Save message --></div>{% endfor %}<br></div> {% endif %} {% endfor %}</div>{% else %}<p>No posts to display yet.</p>{% endif %}<style> .hidden { display: none; }</style>{% endblock %}views.py:
from django.shortcuts import render, redirectfrom usercreatepost.forms import PostFormfrom publication.models import Userpublicationfrom user.models import ProfileMyapp, Subscriptionfrom django.contrib.auth.decorators import login_requiredfrom django.core.paginator import Paginator, EmptyPage, PageNotAnIntegerfrom django.urls import reversefrom django.http import JsonResponsefrom django.template.loader import render_to_stringfrom django.db.models import Q@login_requireddef create_post(request): form = PostForm(request.POST or None) 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 by authors subscribed by the current user subscribed_posts = Userpublication.objects.filter(author__in=subscribed_user_ids) # Get all posts by 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 page object of posts to display page_number = request.GET.get('page', 1) paginator = Paginator(all_posts, 5) # 5 posts per page try: page_posts = paginator.page(page_number) except PageNotAnInteger: page_posts = paginator.page(1) except EmptyPage: page_posts = paginator.page(paginator.num_pages) context = {'form': form, 'post_lists': page_posts, 'title': 'Myapp | News', 'page_number': page_number} return render(request, 'myapp/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)).order_by('-time_create') # Create a Paginator object paginator = Paginator(all_posts, 5) # 5 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 the first page current_page_posts = paginator.page(1) except EmptyPage: # If page number is out of range, return an empty response return JsonResponse({'posts': [], 'next_page_url': None}) # Rendering HTML markup of posts html_posts = render_to_string('myapp/home_list.html', {'posts': current_page_posts}) # Forming a list of posts to pass to JSON posts_list = [{'id': post.id, 'content': post.content} for post in 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 = reverse('load_posts') + f'?page={current_page_posts.next_page_number()}' # Return JSON response with data about the posts, HTML markup, and URL of the next page return JsonResponse({'posts': posts_list, 'html_posts': html_posts, 'next_page_url': next_page_url})