Элегантный способ обработки недействительных страниц в Django с помощью общего представления на основе классов

Я нашел частичное решение в Django: How to catch InvalidPage exception in class-based views?, но URL в адресной строке по-прежнему показывает исходный запрос страницы. В Django есть Paginator.get_page(number), но, похоже, нет способа использовать его для перенаправления внутри представления.

Изначально я думал, что смогу сделать это в get_context_data, но, похоже, я не могу принудительно перенаправить, так как он позволяет только dict в качестве ответа.

def get_context_data(self, **kwargs):
        paginator = self.get_paginator(self.queryset,self.paginate_by,self.paginate_orphans)
        try:
            context = super().get_context_data(**kwargs)
        except Http404 as err:
            self.kwargs['page'] = paginator.get_page(self.request.GET['page']).number
            return redirect('my_list_view', kwargs=self.kwargs)

        context['page_list'] = context['paginator'].get_elided_page_range(context['page_obj'].number,on_each_side=2,on_ends=1)

        return context

Это не работает. Следующий вариант работает (согласно приведенному выше ответу по ссылке), но делает это неоптимальным способом.

def get_context_data(self, **kwargs):
        paginator = self.get_paginator(self.queryset,self.paginate_by,self.paginate_orphans)
        try:
            context = super().get_context_data(**kwargs)
        except Http404 as err:
            self.kwargs['page'] = paginator.get_page(self.request.GET['page']).number
            context = super().get_context_data(**kwargs)

        context['page_list'] = context['paginator'].get_elided_page_range(context['page_obj'].number,on_each_side=2,on_ends=1)

        return context

Мне кажется, что должен быть простой/элегантный способ сделать это, но я просто не нашел его. Конечно, я мог бы использовать представление на основе функций, но я не могу избавиться от ощущения, что должен быть способ сделать это таким образом.

Ну, после некоторой дополнительной работы, это работает, но кажется неэлегантным, в лучшем случае. Я не отмечу это как правильный ответ (пока), потому что он мне не очень нравится, и я надеюсь, что кто-нибудь предложит что-нибудь получше, но я подумал, что могу предложить его. Для руководства я использовал ответы из Redirect from Generic View DetailView in Django.

def get(self, request, *args, **kwargs):
        paginator = self.get_paginator(self.queryset,self.paginate_by,self.paginate_orphans)
        # page = getattr(self.request.GET,'page',None)
        try:
            page = self.request.GET['page']
        except:
            return super().get(request, *args, **kwargs)
        
        # page = self.request.GET['page']
        page_new = paginator.get_page(page)
        try:
            page_int = int(page)
            if page_int != page_new.number:
                redirect_url = reverse_lazy('home') + "?page=" + str(page_new.number)
            else:
                return super().get(request, *args, **kwargs)
        except:
            redirect_url = reverse_lazy('home') + "?page=" + str(page_new.number)
        
        return redirect(redirect_url)
Вернуться на верх