Django пользовательский пагинатор не может перехватить нецелое значение - PullRequest
1 голос
/ 14 апреля 2020

Я хочу использовать свои собственные Paginator в поле зрения на основе ListView. Потребность в пользовательском Paginator возникает из-за двух пользовательских ошибок, которые я хочу поймать: слишком большое число и без номера.

Нет проблем при обнаружении первой проблемы с ошибкой EmptyPage. У меня проблема с отсутствием числовой ошибки - например, ?page=k

Из документации Я бы предположил, что это может быть достигнуто с помощью PageNotAnInteger или обоими с InvalidPage. Вот что я сделал:

class SafePaginator(Paginator):
    def validate_number(self, number):
        try:
            return super(SafePaginator, self).validate_number(number)
        except InvalidPage:
            return 1

К сожалению, все еще, когда я тестирую опцию ?page=k, я получаю сообщение об ошибке:

Страница не является 'последней', и не может

?page=last работает правильно

Это, кажется, исходит от ListView paginate_queryset, как вы можете видеть на GitHub

def paginate_queryset(self, queryset, page_size):
        """Paginate the queryset, if needed."""
        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.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)
            })

Но не вызывать ли его после проверки valid_number? Кроме того, я попытался добавить except ValueError, что также не помогает.

Есть ли другой способ, как я должен поймать эту ошибку?

1 Ответ

1 голос
/ 14 апреля 2020

Но не должен ли он быть вызван после проверки valid_number? Кроме того, я попытался добавить, кроме ValueError, который также не помогает.

Нет , поскольку, как вы можете видеть, он пытается преобразовать это с int(page). Если , что терпит неудачу, он поднимет ValueError и проверит на 'last'. Так что pagiantor.page(page_number) никогда не выполняется при сбое int(page), а page не 'last'.

Добавление except ValueError также не поможет, поскольку опять-таки управление никогда не передается методу .page() и, следовательно, методу validate_number().

Решением может быть просто заменить значение на 1, например:

from django.http import Http404

class MyListView(ListView):
    # …

    def <b>paginate_queryset</b>(self, queryset, page_size):
        try:
            return super().paginate_queryset(self, queryset, page_size)
        except Http404:
            paginator = self.get_paginator(
                queryset, page_size, orphans=self.get_paginate_orphans(),
                allow_empty_first_page=self.get_allow_empty())
            try:
                page = paginator.page(1)
                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)
                })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...