You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django类视图分页异常:搜索查询翻页后丢失致无结果

问题原因分析

嘿,我来帮你搞定这个分页问题!你遇到的核心问题是分页链接没有携带搜索查询参数q:当点击下一页时,请求URL里只保留了page=2,丢失了关键的q=love参数。这导致视图中query为空,触发了queryset_list = Song.objects.none()的逻辑——空的查询集自然无法分页,所以才会抛出"Invalid page (2): That page contains no results"的错误。

解决方案

我们需要修改分页链接,让它在跳转时保留搜索的q参数,下面提供两种实用的实现方式:

方式一:直接在模板中拼接查询参数

这是最直接的修改方式,只需调整search.html里的分页链接,把当前的q参数添加到每个分页URL中:

{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?q={{ request.GET.q }}&page={{ page_obj.previous_page_number }}">&laquo;</a></li>
{% else %}
<li class="disabled"><span>&laquo;</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li><a href="?q={{ request.GET.q }}&page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?q={{ request.GET.q }}&page={{ page_obj.next_page_number }}">&raquo;</a></li>
{% else %}
<li class="disabled"><span>&raquo;</span></li>
{% endif %}
</ul>
{% endif %}

这样每次点击分页按钮时,URL都会带上q参数,视图就能正确获取搜索条件,返回对应的查询集完成分页。

方式二:在视图中传递查询参数到模板(更优雅)

如果你想让代码结构更清晰,可以在视图里把查询参数存入上下文,再在模板中调用:

1. 更新views.py中的Search视图

添加get_context_data方法,把搜索查询参数传递到模板:

from django.views import generic
from .models import Album, Song
from django.db.models import Q

class Search(generic.ListView):
    template_name = 'music/search.html'
    paginate_by = 5

    def get_queryset(self, *args, **kwargs):
        queryset_list = Song.objects.all()
        query = self.request.GET.get('q')
        if query:
            queryset_list = queryset_list.filter(
                Q(song_title__icontains=query)| Q(file_type__icontains=query)
            ).distinct()
        if not query:
            queryset_list = Song.objects.none()
        return queryset_list  # 注意你之前写了两个重复的return,删掉一个即可

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 把搜索查询参数存入上下文,方便模板调用
        context['search_query'] = self.request.GET.get('q', '')
        return context

2. 修改search.html中的分页链接

用上下文里的search_query代替直接调用request.GET.q:

{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?q={{ search_query }}&page={{ page_obj.previous_page_number }}">&laquo;</a></li>
{% else %}
<li class="disabled"><span>&laquo;</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li><a href="?q={{ search_query }}&page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?q={{ search_query }}&page={{ page_obj.next_page_number }}">&raquo;</a></li>
{% else %}
<li class="disabled"><span>&raquo;</span></li>
{% endif %}
</ul>
{% endif %}
额外小优化

你视图里的get_queryset方法有两个重复的return queryset_list,虽然不影响功能,但建议删掉一个,让代码更整洁。

内容的提问来源于stack exchange,提问作者Rashid Aziz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:18:23