页面选择排序选项后显示重复对象问题求助
问题原因分析
未分页QuerySet触发HTMX重复加载
你的dropdown_selected视图返回的是未分页的全部帖子QuerySet,但首页home视图原本使用分页逻辑。home_page_pagination.html中最后一个帖子的div带有HTMX的hx-get属性,用于触发下一页加载,但dropdown_selected视图没有传递page_obj上下文变量,导致{{ page_obj.number|add:1 }}渲染为空,HTMX最终请求的URL会变成/posts/home?page=(无有效页码)。页面重载后,HTMX检测到最后一个div进入视口,会触发这个无效请求,而home视图默认返回第一页内容,导致第一页帖子被追加到已显示的全部帖子后,造成重复显示。模板结构冗余
home_page.html末尾的</body></html>是多余的,如果该模板继承自base模板,base模板已经包含这些标签,重复添加会导致HTML结构异常,可能引发渲染问题。
解决办法
方法1:复用首页逻辑,重定向携带排序参数
修改dropdown_selected视图,直接重定向到首页并携带排序参数,保持分页逻辑统一:
from django.shortcuts import redirect, reverse def dropdown_selected(request): selection = request.GET.get('sort_by') # 重定向到首页,传递排序参数 return redirect(f"{reverse('posts:home')}?sort_by={selection}")
然后修改首页home视图,支持接收sort_by参数并处理排序:
from django.core.paginator import Paginator def home(request): sort_by = request.GET.get('sort_by', 'newest') # 默认按最新排序 if sort_by == "most_supported": posts = Post.objects.annotate(n_supporters=Count('supporters')).order_by('-n_supporters') elif sort_by == "oldest": posts = Post.objects.all().order_by('date') else: posts = Post.objects.all().order_by('-date') # 保持原有的分页逻辑 paginator = Paginator(posts, 10) # 按实际需求设置每页数量 page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) context = { 'object_list': page_obj.object_list, 'page_obj': page_obj, 'home_search': False } return render(request, "home_page.html", context)
方法2:直接在排序视图中添加分页逻辑
如果不想重定向,可直接在dropdown_selected视图中处理分页:
from django.core.paginator import Paginator def dropdown_selected(request): selection = request.GET.get('sort_by') page_number = request.GET.get('page', 1) if selection == "most_supported": posts = Post.objects.annotate(n_supporters=Count('supporters')).order_by('-n_supporters') elif selection == "newest": posts = Post.objects.all().order_by('-date') else: posts = Post.objects.all().order_by('date') # 添加分页处理 paginator = Paginator(posts, 10) page_obj = paginator.get_page(page_number) context = { 'object_list': page_obj.object_list, 'page_obj': page_obj, 'home_search': False } return render(request, "home_page.html", context)
额外修复:清理模板冗余代码
删除home_page.html末尾多余的</body></html>标签,确保模板继承base模板时结构正确:
<!-- 保留到 endblock 即可 --> {% endblock content %} <!-- 删除下面的 </body></html> -->
可选优化:排序时保留当前页码
修改排序表单,添加隐藏字段传递当前页码,避免排序后回到第一页:
<form action="{% url 'posts:dropdown_selected' %}" method="get" name="sort_form"> <select class="rounded border-gray-200" name="sort_by" onchange="sort_form.submit()"> <option id="" value="placeholder" disabled selected hidden>Sort By</option> <option value="most_supported">Most Supported</option> <option value="newest">Newest</option> <option value="oldest">Oldest</option> </select> <!-- 传递当前页码 --> {% if page_obj %} <input type="hidden" name="page" value="{{ page_obj.number }}"> {% endif %} </form>
内容的提问来源于stack exchange,提问作者Callum
相关产品推荐
相关产品推荐

