Элегантный способ обработки недействительных страниц в 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)