Как разбить список на основе классов с помощью django-filters

Ребята, вы знаете, как разбить на страницы общий ListView на основе классов, который использует django-фильтры в качестве панели поиска? Когда я прочитал некоторые статьи по этой проблеме (чего было не так много для представлений на основе классов), мне показалось, что фильтры django и разбиение на страницы не очень хорошо работают вместе. Вот мой взгляд:

class StudentListView(OrganisorAndLoginRequiredMixin, generic.ListView):
    template_name = "leads/student_list.html"
    context_object_name = "leads"

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

    def get_queryset(self):
        organisation = self.request.user.userprofile
        return Lead.objects.filter(organisation=organisation).order_by('first_name')

Я был бы очень признателен, если бы вы, ребята, могли сказать мне, какой код мне нужно написать для моего представления, а также какой код мне нужно добавить в мой шаблон, чтобы разбивка на страницы работала. Я не думаю, что код для фактического фильтра и шаблона необходим, но если вам это нужно, я могу добавить его к этому вопросу. Спасибо.

Для получения дополнительной информации я собираюсь добавить в свой шаблон следующий код разбиения на страницы:

{% if is_paginated %}
  <div class="pagination">
      <span class="page-links">
          {% if page_obj.has_previous %}
              <a href="{{ request.path }}?page={{ page_obj.previous_page_number }}">previous</a>
          {% endif %}
          <span class="page-current">
              Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
          </span>
          {% if page_obj.has_next %}
              <a href="{{ request.path }}?page={{ page_obj.next_page_number }}">next</a>
          {% endif %}
      </span>
  </div>
{% endif %}

person code builder    schedule 05.04.2021    source источник


Ответы (1)


Вы должны использовать FilterView, который предоставлено django-filter. Также этот класс наследуется от MultipleObjectMixin, поэтому он способен выполнять разбиение на страницы, поэтому, если вы установите атрибут paginate_by в классе, он также будет выполнять разбиение на страницы:

from django_filters.views import FilterView


class StudentListView(OrganisorAndLoginRequiredMixin, FilterView):
    template_name = "leads/student_list.html"
    context_object_name = "leads"
    filterset_class = StudentFilter
    paginate_by = 10 # Change as per your preference
    
    def get_queryset(self):
        organisation = self.request.user.userprofile
        return Lead.objects.filter(organisation=organisation).order_by('first_name')
person Abdul Aziz Barkat    schedule 05.04.2021
comment
Спасибо за комментарий. Хотя поисковая строка работает нормально. Проблема, которую я не знаю, как решить, заключается в том, как разбить этот список на страницы. - person code builder; 05.04.2021
comment
@JohnSong FilterView наследуется от MultipleObjectMixin, поэтому он может выполнять разбиение на страницы за вас. Я отредактировал ответ, чтобы показать, как это сделать - person Abdul Aziz Barkat; 05.04.2021
comment
Итак, я собираюсь добавить код, добавленный к вопросу выше, в свои шаблоны. Сначала я также написал {% for lead в filter.qs %} в цикле for. Как мне изменить filter.qs, чтобы это работало? - person code builder; 05.04.2021
comment
{% for lead in object_list %} или в соответствии с вашим context_object_name используйте {% for lead in leads %} (также контекст будет иметь переменную filter, также будут доступны все переменные, которые вы ожидаете, такие как page_obj и т. д.) - person Abdul Aziz Barkat; 05.04.2021
comment
Он работает гладко человек. Большое спасибо! - person code builder; 05.04.2021