如何在ListView Django中进行筛选和分页

2024-09-30 16:41:04 发布

您现在位置:Python中文网/ 问答频道 /正文

当我想对使用django_filter创建的筛选器进行分页时,我遇到了一个问题,在我的模板中,它显示了查询集和筛选器,但分页不起作用,我想知道为什么会发生这种情况,以及您是否可以帮我

我将插入代码片段,以便您可以看到

这是我的观点

我有所有必要的进口货

@method_decorator(staff_member_required, name='dispatch')
class EmployeeListView(ListView):
    model = Employee
    paginate_by = 4

    def dispatch(self, request, *args, **kwargs):
        if not request.user.has_perm('employee.view_employee'):
            return redirect(reverse_lazy('home'))
        return super(EmployeeListView, self).dispatch(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = EmployeeFilter(self.request.GET, queryset = self.get_queryset())
        return context

过滤器.py

import django_filters
from .models import Employee, Accident

class EmployeeFilter(django_filters.FilterSet):

    class Meta:
        model = Employee
        fields = {
            'rutEmployee' : ['startswith']
        }

Tags: djangoselfgetmodelreturnrequestdefcontext
2条回答

您应该重写get_queryset。这意味着您必须将筛选器放入get_queryset中,如下所示:

@method_decorator(staff_member_required, name='dispatch')
class EmployeeListView(ListView):
    model = Employee
    paginate_by = 4

    def dispatch(self, request, *args, **kwargs):
        if not request.user.has_perm('employee.view_employee'):
            return redirect(reverse_lazy('home'))
        return super(EmployeeListView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = EmployeeFilter(self.request.GET, queryset = self.get_queryset())
        return context
    
    def get_queryset(self):
        queryset = super().get_queryset()
        return EmployeeFilter(self.request.GET, queryset=queryset).qs

并在employee_list.html中使用object_list而不是filter,如下所示:

{% for employee in object_list|dictsort:"id" reversed %}

您也可以尝试以下方法: (我源代码中的一个片段)

class ModelListView(ListView):
    model = YourModel
    paginate_by = 4 # Change this if you don't intend to paginate by 4
    ordering = model_field_to_order_by
    # variable used to know if a match was found for the search made using django_filters
    no_search_result = False

    def get_queryset(self, **kwargs):
        search_results = YourDjangoFiltersForm(self.request.GET, self.queryset)
        self.no_search_result = True if not search_results.qs else False
        # Returns the default queryset if an empty queryset is returned by the django_filters
        # You could as well return just the search result's queryset if you want to
        return search_results.qs.distinct() or self.model.objects.all()

    def get_query_string(self):
        query_string = self.request.META.get("QUERY_STRING", "")
        # Get all queries excluding pages from the request's meta
        validated_query_string = "&".join([x for x in re.findall(
            r"(\w*=\w{1,})", query_string) if not "page=" in x])
        # Avoid passing the query path to template if no search result is found using the previous query
        return "&" + validated_query_string.lower() if (validated_query_string and not self.no_search_result) else ""

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Pass to template if you want to do something whenever an empty queryset is return by django_filters
        context["no_search_result"] = self.no_search_result
        # This is the query string which should be appended to the current page in your template for pagination, very critical
        context["query_string"] = self.get_query_string()
        context['filter'] = YourDjangoFiltersForm()
        return context

在html模板中,您需要附加从视图传递到模板的querystring,下面显示了一个示例

{% for i in page_obj.paginator.page_range %}
    {% if page_obj.number == i %}
          <li class="page-item active" aria-current="page">
            <span class="page-link">{{ i }}<span class="sr-only">(current)</span></span>
          </li>
          {% elif i > page_obj.number|add:'-5' and i < page_obj.number|add:'5' %} <li class="page-item"><a
              class="page-link" href="?page={{ i }}{{ query_string }}">{{ i }}</a></li>
    {% endif %}
{% endfor %}

相关问题 更多 >