Django пагинация: EmptyPage: Эта страница не содержит результатов

При использовании Django CBV ListView с пагинацией:

class Proposals(ListView):
    model = Proposal
    ordering = "id"
    paginate_by = 10

В браузере, если я предоставляю страницу, которая находится вне диапазона, я получаю ошибку:

enter image description here

Я хотел бы иметь другое поведение: возврат к последней существующей странице, если указанная страница находится вне диапазона.

Я покопался в файле paginator.py исходного кода Django и с удивлением обнаружил код, который делает именно это:

    def get_page(self, number):
        """
        Return a valid page, even if the page argument isn't a number or isn't
        in range.
        """
        try:
            number = self.validate_number(number)
        except PageNotAnInteger:
            number = 1
        except EmptyPage:
            number = self.num_pages
        return self.page(number)

Однако, похоже, что этот код никогда не вызывается по умолчанию при использовании Pagination. Как правильно поступить в этом случае? Должен ли я создать свой собственный пагинатор, подклассифицировав класс Paginator?

Спасибо.

Единственное решение, которое я нашел, это переопределение метода paginate_queryset. Однако мне это не нравится, так как я вынужден переписывать всю логику, в то время как я хочу изменить только одну строку.

Открыт для любого лучшего предложения.

class PermissivePaginationListView(ListView):
    def paginate_queryset(self, queryset, page_size):
        """
        This is an exact copy of the original method, jut changing `page` to `get_page` method to prevent errors with out of range pages.
        This is useful with HTMX, when the last row of the table is deleted, as the current page in URL is not valid anymore because there is no result in it.
        """
        paginator = self.get_paginator(
            queryset,
            page_size,
            orphans=self.get_paginate_orphans(),
            allow_empty_first_page=self.get_allow_empty(),
        )
        page_kwarg = self.page_kwarg
        page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
        try:
            page_number = int(page)
        except ValueError:
            if page == "last":
                page_number = paginator.num_pages
            else:
                raise Http404(_("Page is not “last”, nor can it be converted to an int."))
        try:
            page = paginator.get_page(page_number)
            return (paginator, page, page.object_list, page.has_other_pages())
        except InvalidPage as e:
            raise Http404(
                _("Invalid page (%(page_number)s): %(message)s")
                % {"page_number": page_number, "message": str(e)}
            )
Вернуться на верх