如何在Django-Filter的函数视图中实现搜索结果分页功能
Django-Filter 函数视图添加分页实现方案
步骤1:修改 views.py 新增分页逻辑
首先导入Django内置分页工具,修改stock_search函数,在筛选结果基础上完成分页,同时保留筛选查询参数避免换页时筛选条件丢失:
from django.shortcuts import render from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from .models import Stock from .filters import StockFilter def home(request): return render(request, 'stockwatcher/home.html', {'title': 'Home'}) def stock_search(request): f = StockFilter(request.GET, queryset=Stock.objects.all()) # 配置分页规则,第二个参数为每页展示条数,可自行调整 paginator = Paginator(f.qs, 9) page = request.GET.get('page') # 处理页码异常 try: page_obj = paginator.page(page) except PageNotAnInteger: # 页码非整数时返回第一页 page_obj = paginator.page(1) except EmptyPage: # 页码超出范围时返回最后一页 page_obj = paginator.page(paginator.num_pages) # 生成不含page参数的查询串,换页时保留筛选条件 query_params = request.GET.copy() if 'page' in query_params: del query_params['page'] query_string = query_params.urlencode() return render(request, 'stockwatcher/search_results.html', { 'filter': f, 'page_obj': page_obj, 'is_paginated': paginator.num_pages > 1, 'query_string': query_string })
步骤2:修改 search_results.html 适配分页
首先替换列表遍历的数据源,再放开原有分页注释并修改链接,带上筛选查询参数:
{% extends "stockwatcher/base.html" %} {% block content %} {% load widget_tweaks %} <div class="container"> <div class="row" style="padding: 50px;"> <form method="get"> {{ filter.form.as_p }} <input type="submit" /> </form> </div> <div class="row"> <!-- 替换遍历数据源为page_obj --> {% for stock in page_obj %} <div class="col-4"> <div class="card text-white bg-info mb-3" style="max-width: 18rem;"> <div class="card-header">{{stock.transaction_date}}</div> <div class="card-body"> <h5 class="card-title" style="color: white"> {{stock.ticker}} </h5> <p class="card-text">{{stock.senator}} - {{stock.type}}</p> </div> </div> </div> {% endfor %} </div> <!-- 放开分页代码并新增查询串拼接逻辑 --> {% if is_paginated %} {% if page_obj.has_previous %} <a class="btn btn-outline-info mb-4" href="?{{ query_string }}&page=1">First</a> <a class="btn btn-outline-info mb-4" href="?{{ query_string }}&page={{ page_obj.previous_page_number }}">Previous</a> {% endif %} <!-- 新增中间页码展示,可根据需求删除 --> {% for num in page_obj.paginator.page_range %} {% if page_obj.number == num %} <a class="btn btn-info mb-4" href="?{{ query_string }}&page={{ num }}">{{ num }}</a> {% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %} <a class="btn btn-outline-info mb-4" href="?{{ query_string }}&page={{ num }}">{{ num }}</a> {% endif %} {% endfor %} {% if page_obj.has_next %} <a class="btn btn-outline-info mb-4" href="?{{ query_string }}&page={{ page_obj.next_page_number }}">Next</a> <a class="btn btn-outline-info mb-4" href="?{{ query_string }}&page={{ page_obj.paginator.num_pages }}">Last</a> {% endif %} {% endif %} {% endblock content %}
可选配置检查
如果模板无法正常获取参数,确认settings.py中TEMPLATES配置的context_processors包含以下项:
'django.template.context_processors.request'
内容的提问来源于stack exchange,提问作者SL.
相关产品推荐
相关产品推荐

