Django类视图ListView实现带过滤和分页的列表时过滤不生效如何解决?
问题根因
你模板中调用的invoices_filtered_list是get_queryset方法内的局部变量,没有传递到模板上下文,所以过滤器表单无法正常渲染,过滤功能自然不生效。另外你现有分页链接仅携带page参数,翻页时会丢失已输入的过滤条件。
修改步骤
1. 重写views.py的get_context_data方法,传递过滤器实例到模板
修改后的views.py完整代码:
from django.views.generic import ListView from .models import WoodhistAzolveInvoices from .filters import WoodhistAzolveInvoicesFilter class InvoicesListView(ListView): model = WoodhistAzolveInvoices template_name = 'home.html' context_object_name = 'invoices' ordering = ['suppliername', 'invoicenumber'] paginate_by = 50 def get_queryset(self): qs = super().get_queryset() # 将过滤器实例存到对象属性,方便后续调用 self.invoice_filter = WoodhistAzolveInvoicesFilter(self.request.GET, queryset=qs) return self.invoice_filter.qs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 传递过滤器实例到模板,对应模板中调用的变量名 context['invoices_filtered_list'] = self.invoice_filter # 提取当前除page外的所有查询参数,用于分页时保留过滤条件 context['query_params'] = self.request.GET.copy() if 'page' in context['query_params']: del context['query_params']['page'] return context
2. 修改home.html中的分页链接,保留过滤参数
将原有分页的href属性统一修改为以下格式,拼接已有的过滤参数:
{% if is_paginated %} {% if page_obj.has_previous %} <a class="btn btn-outline-info" href="?page=1&{{ query_params.urlencode }}">First</a> <a class="btn btn-outline-info" href="?page={{ page_obj.previous_page_number}}&{{ query_params.urlencode }}">Previous</a> {% endif %} {% for num in page_obj.paginator.page_range %} {% if page_obj.number == num %} <a class="btn btn-info" href="?page={{ num }}&{{ query_params.urlencode }}"> {{ num }}</a> {% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %} <a class="btn btn-outline-info" href="?page={{ num }}&{{ query_params.urlencode }}"> {{ num }}</a> {% endif %} {% endfor %} {% if page_obj.has_next %} <a class="btn btn-outline-info" href="?page={{ page_obj.next_page_number }}&{{ query_params.urlencode }}">Next</a> <a class="btn btn-outline-info" href="?page={{ page_obj.paginator.num_pages }}&{{ query_params.urlencode }}">Last</a> {% endif %} {% endif %}
额外检查项
如果修改后仍看不到过滤器表单,先确认settings.py的INSTALLED_APPS列表中已经添加了django_filters。
内容的提问来源于stack exchange,提问作者Baldie47
相关产品推荐
相关产品推荐

