如何解决Django网站中Filter过滤器与Paginator分页器无法同时生效问题
问题根源
- 分页器使用了未过滤的全量数据集,而非过滤后的查询结果,导致过滤和分页的数据源不统一
- 分页跳转链接未携带过滤参数,切换页码时过滤条件丢失
- filters.py中存在笔误,可能导致过滤规则不生效
修复步骤
1. 修改views.py中的分页逻辑
将分页器的数据源替换为过滤后的查询集:
def posts(request): cars = Userpost.objects.all() myFilter = UserpostFilter(request.GET, queryset=cars) # 拿到过滤后的结果集 filtered_cars = myFilter.qs # 分页器使用过滤后的结果,而非全量数据 p = Paginator(filtered_cars, 2) page = request.GET.get('page') cars_list = p.get_page(page) nums = "a" * cars_list.paginator.num_pages context = {"myFilter":myFilter, 'cars_list':cars_list, "nums":nums} return render(request, 'store/userposts.html', context)
2. 修复userposts.html模板
- 列表循环改为使用分页后的数据集
cars_list - 所有分页链接新增过滤参数携带逻辑,避免切换页码时过滤条件丢失
{% extends 'store/main.html' %} {% load static %} {% block content %} <div class = 'row'> <div class = 'col'> <div class = 'card card-body'> <form method="get"> {{myFilter.form}} <button class="btn btn-primary" type = "submit">Search</button> </form> </div> </div> </div> <div class="row"> <!-- 循环改为分页后的过滤结果 --> {% for car in cars_list %} <div class="col-lg-4"> <img class="thumbnail" src="{{car.imageURL|default:'/images/transparentLogo.png'}}"> <div class="box-element product"> <h6><strong>{{car.Year}} {{car.Make}} {{car.Model}}</strong></h6> <hr> <a class="btn btn-outline-success" href="{% url 'post_detail' car.pk %}">View</a> <h4 style="display: inline-block; float: right"><strong>${{car.Price|floatformat:2}}</strong></h4> </div> </div> {% endfor %} </div> <nav aria-label="Page navigation"> <ul class="pagination"> {% if cars_list.has_previous %} <li class="page-item"> <!-- 链接携带现有过滤参数 --> <a class="page-link" href="?{% for k,v in request.GET.items %}{% if k != 'page' %}{{k}}={{v}}&{% endif %}{% endfor %}page=1" aria-label="Previous"> <span aria-hidden="true">«</span> <span class="sr-only">begin</span> </a> </li> {% endif %} {% for n in cars_list.paginator.page_range %} {% if cars_list.number == n %} <li class="page-item active"> <span class="page-link">{{ n }}<span class="sr-only">(current)</span></span> </li> {% elif n > cars_list.number|add:'-3' and n < cars_list.number|add:'3' %} <!-- 链接携带现有过滤参数 --> <li class="page-item"><a class="page-link" href="?{% for k,v in request.GET.items %}{% if k != 'page' %}{{k}}={{v}}&{% endif %}{% endfor %}page={{ n }}">{{ n }}</a></li> {% endif %} {% endfor %} {% if cars_list.has_next %} <li class="page-item"> <!-- 链接携带现有过滤参数 --> <a class="page-link" href="?{% for k,v in request.GET.items %}{% if k != 'page' %}{{k}}={{v}}&{% endif %}{% endfor %}page={{ cars_list.paginator.num_pages }}" aria-label="Next"> <span aria-hidden="true">»</span> <span class="sr-only">end</span> </a> </li> {% endif %} </ul> </nav> <br/> {% endblock content %}
3. 修复filters.py的笔误
将field = '__all__'改为fields = '__all__',避免过滤规则加载失败:
class UserpostFilter(django_filters.FilterSet): start_date = DateFilter(field_name = "date_published", lookup_expr = 'gte') end_date = DateFilter(field_name = "date_published", lookup_expr = 'lte') min_price = django_filters.NumberFilter(field_name="Price", lookup_expr='gte') max_price = django_filters.NumberFilter(field_name="Price", lookup_expr='lte') class Meta: model = Userpost # 修正为fields fields = '__all__' exclude = 'image', 'user', 'Price', 'Email', 'date_published'
4. 确认请求上下文配置
检查项目settings.py中TEMPLATES配置,确保已加入request上下文处理器,否则模板无法获取request对象携带的过滤参数:
TEMPLATES = [ { # ... 其他配置 'OPTIONS': { 'context_processors': [ # ... 其他处理器 'django.template.context_processors.request', # 新增这行(如果不存在的话) ], }, }, ]
内容的提问来源于stack exchange,提问作者Gabriel Trezza
相关产品推荐
相关产品推荐

