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

Django 3.1搜索分页第二页及以后空白问题求助

Absolutely, the missing keywords parameter in your pagination URLs is exactly why the second page (and beyond) shows up blank! Let me break down the problem and fix it for you:

Why This Happens

When you click a pagination link, your current code only adds the page parameter to the URL, but it doesn't carry over the original keywords parameter. So when the view receives the request for ?page=2, there's no keywords in request.GET—it hits the else branch and returns the empty search page instead of filtered results.


Fix 1: Quick & Simple (Pass Keywords Directly)

The easiest fix is to modify your template pagination links to include the keywords value from the original request. Update your HTML code like this:

<div class="col-md-12">
    {% if queries.has_other_pages %}
    <ul class="pagination">
        {% if queries.has_previous %}
        <li class="page-item">
            <a href="?keywords={{ request.GET.keywords }}&page={{ queries.previous_page_number }}" class="page-link">&laquo;</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link">&laquo;</a>
        </li>
        {% endif %}
        {% for i in queries.paginator.page_range %}
        {% if queries.number == i %}
        <li class="page-item active">
            <a class="page-link">{{i}}</a>
        </li>
        {% else %}
        <li class="page-item">
            <a href="?keywords={{ request.GET.keywords }}&page={{i}}" class="page-link">{{i}}</a>
        </li>
        {% endif %}
        {% endfor %}
        {% if queries.has_next %}
        <li class="page-item">
            <a href="?keywords={{ request.GET.keywords }}&page={{ queries.next_page_number }}" class="page-link">&raquo;</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link">&raquo;</a>
        </li>
        {% endif %}
    </ul>
    {% endif %}
</div>

Fix 2: Robust & Scalable (Preserve All Query Params)

If you ever add more search filters (like category, date ranges, etc.), the above method will fail to carry those over. A better approach is to preserve all existing query parameters except the page value:

  1. Update your views.py to pass cleaned query parameters to the template:
def search(request):
    # Keywords
    if 'keywords' in request.GET:
        keywords = request.GET['keywords']
        if keywords:
            # Use Q objects for cleaner, database-level filtering (avoids memory-heavy deduping)
            from django.db.models import Q
            result_list_control_valves = queryset_list.filter(
                Q(title__icontains=keywords) | Q(description__icontains=keywords)
            ).distinct().order_by('title')
            
            paginator = Paginator(result_list_control_valves, 1)
            page = request.GET.get('page')
            paged_queries = paginator.get_page(page)
            
            # Preserve all query params except 'page'
            query_params = request.GET.copy()
            query_params.pop('page', None)
            
            context = {
                'queries': paged_queries,
                'query_params': query_params.urlencode()
            }
            return render(request, 'pages/search.html', context)
        else:
            return render(request, 'pages/search.html')
    else:
        return render(request, 'pages/search.html')
  1. Update your template to use these preserved parameters:
<div class="col-md-12">
    {% if queries.has_other_pages %}
    <ul class="pagination">
        {% if queries.has_previous %}
        <li class="page-item">
            <a href="?{{ query_params }}&page={{ queries.previous_page_number }}" class="page-link">&laquo;</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link">&laquo;</a>
        </li>
        {% endif %}
        {% for i in queries.paginator.page_range %}
        {% if queries.number == i %}
        <li class="page-item active">
            <a class="page-link">{{i}}</a>
        </li>
        {% else %}
        <li class="page-item">
            <a href="?{{ query_params }}&page={{i}}" class="page-link">{{i}}</a>
        </li>
        {% endif %}
        {% endfor %}
        {% if queries.has_next %}
        <li class="page-item">
            <a href="?{{ query_params }}&page={{ queries.next_page_number }}" class="page-link">&raquo;</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link">&raquo;</a>
        </li>
        {% endif %}
    </ul>
    {% endif %}
</div>

Bonus: Optimize Your Search Logic

Your original code uses chain and dict.fromkeys to combine and deduplicate results, which pulls all matching records into memory first. Using Django's Q objects lets the database handle filtering and deduplication directly—this is faster, more efficient, and cleaner.

Why This Works

Now when you click a pagination link, the URL will include both the keywords parameter (and any future filters you add) along with the page number. Your view will receive the keywords again, re-run the search, and return the correct page of results.

内容的提问来源于stack exchange,提问作者Shahriar.M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:47:39