如何在Django项目模板中用jQuery/AJAX添加加载更多评论按钮
实现方案
你只需要做3处调整即可完成功能,全程不需要复杂的JS知识,代码可以直接复用:
1. 后端视图调整(Django端)
首先用Django自带的分页工具实现评论分页,同时新增一个接口返回分页的评论内容:
# views.py from django.core.paginator import Paginator from django.http import JsonResponse from django.shortcuts import render from .models import Comment # 替换成你自己的评论模型 # 你原来的profile页面视图 def profile(request): all_comments = Comment.objects.all().order_by('-updated_date') # 替换成你自己的评论查询逻辑 paginator = Paginator(all_comments, 5) # 每次加载5条,可自行修改数量 first_page_comments = paginator.page(1) return render(request, 'profile.html', {'comments': first_page_comments, 'total_comments': all_comments.count()}) # 新增的加载更多评论接口 def load_more_comments(request): page = request.GET.get('page', 1) all_comments = Comment.objects.all().order_by('-updated_date') paginator = Paginator(all_comments, 5) try: comments = paginator.page(page) except: return JsonResponse({'html': '', 'has_more': False}) # 渲染评论片段,结构和模板内的li结构完全一致 html = '' for comment in comments: star_html = ''.join(['<i class="fas fa-star filled"></i>' for _ in range(comment.star)]) none_star_html = ''.join(['<i class="fas fa-star"></i>' for _ in range(comment.none_star)]) html += f''' <li> <div class="comment"> <img class="avatar avatar-sm rounded-circle" alt="用户头像" src="{comment.comment_user.image.url}"> <div class="comment-body"> <div class="meta-data"> <span style="white-space:pre" class="comment-author">{comment.comment_user.unvan} {comment.comment_user.get_full_name()}</span> <span class="comment-date">{comment.updated_date|timesince}}</span> <div class="review-count rating"> {star_html} {none_star_html} </div> </div> <p class="comment-content"> {comment.comment} </p> </div> </div> </li> ''' return JsonResponse({'html': html, 'has_more': comments.has_next()})
之后在路由文件中新增接口路由:
# urls.py urlpatterns = [ # 保留你原来的其他路由 path('load-more-comments/', views.load_more_comments, name='load_more_comments'), ]
2. profile.html模板调整
只需要修改原有模板的两处细节:
- 按钮id去掉前缀的
#,新增页码、是否有更多内容的自定义属性 - 按钮上的总评论数替换为视图传入的
total_comments变量
修改后的完整模板代码:
<div class="widget review-listing"> <ul class="comments-list" id="loadmorecomment"> {% if comments %} {% for comment in comments %} <li> <div class="comment"> <img class="avatar avatar-sm rounded-circle" alt="用户头像" src="{{comment.comment_user.image.url}}"> <div class="comment-body"> <div class="meta-data"> <span style="white-space:pre" class="comment-author">{{comment.comment_user.unvan}} {{comment.comment_user.get_full_name}}</span> <span class="comment-date">{{ comment.updated_date|timesince }}</span> <div class="review-count rating"> {% if comment.star != 0 %} {% for i in comment.star|rjust:comment.star %} <i class="fas fa-star filled"></i> {% endfor %} {% endif %} {% if comment.none_star != 0 %} {% for i in comment.none_star|rjust:comment.none_star %} <i class="fas fa-star"></i> {% endfor %} {% endif %} </div> </div> <p class="comment-content"> {{comment.comment}} </p> </div> </div> </li> {% endfor %} {% else %} <p style="color: orange;">暂无评论</p> {% endif %} </ul> <!-- 加载更多按钮 --> <div class="all-feedback text-center"> <a id="loadMore" name="more_comments" href="javascript:;" data-page="1" data-has-more="true" class="btn btn-primary btn-sm"> 加载更多评论 <strong>({{total_comments}})</strong> </a> </div> <!-- /加载更多按钮 --> </div>
3. 添加原生JS代码
把以下代码直接复制到profile.html的</body>标签之前即可,不需要理解逻辑直接复用:
<script> document.addEventListener('DOMContentLoaded', function() { const loadMoreBtn = document.getElementById('loadMore'); const commentList = document.getElementById('loadmorecomment'); loadMoreBtn.addEventListener('click', function(e) { e.preventDefault(); // 没有更多评论时直接返回 if (loadMoreBtn.dataset.hasMore === 'false') { loadMoreBtn.innerText = '没有更多评论了'; return; } // 计算下一页页码 let currentPage = parseInt(loadMoreBtn.dataset.page); let nextPage = currentPage + 1; // 切换按钮加载状态 loadMoreBtn.innerText = '加载中...'; // 请求更多评论 fetch(`/load-more-comments/?page=${nextPage}`) .then(res => res.json()) .then(data => { // 把新评论插入到列表末尾 commentList.insertAdjacentHTML('beforeend', data.html); // 更新页码 loadMoreBtn.dataset.page = nextPage; // 更新是否有更多内容的标记 loadMoreBtn.dataset.hasMore = data.has_more; // 恢复按钮文字 loadMoreBtn.innerText = data.has_more ? '加载更多评论' : '没有更多评论了'; }) .catch(err => { loadMoreBtn.innerText = '加载失败,请重试'; }); }); }); </script>
提示:如果要调整每次加载的评论数量,只需同步修改views.py里两个Paginator实例的第二个参数即可。
内容的提问来源于stack exchange,提问作者Muhammet Aydoğan
相关产品推荐
相关产品推荐

