У Django есть проблема с нумерацией страниц по умолчанию ListView
, заключающаяся в том, что при доступе к представлению списка с номером страницы, выходящим за пределы диапазона, что обычно может произойти, когда я обновляю последнюю страницу, когда некоторые объекты удаляются, поэтому общее количество страниц уменьшается, Django выдаст ошибку 404.
В этом случае я хочу показать страницу с предупреждающим сообщением о том, что номер страницы больше недействителен, и нумерацией страниц, которые могут привести пользователя к действительной странице.
Так вот мой код
from django.views.generic import ListView
from django.shortcuts import render
from django.http import Http404
class MyListView(ListView):
def get(self, request, *args, **kwargs):
try:
return super().get(request, *args, **kwargs)
except Http404:
return render(request, 'pagenum_out_of_range.html', status=404)
model = MyModel
context_object_name = 'my_models'
template_name = 'my_models_list.html'
paginate_by = 20
и pagenum_out_of_range.html
{% extends my_project_base_template %}
{% block body %}
<p>Invalid page number and there's no result here. Please try somewhere else.</p>
{% for object in page_obj.paginator.page_range %}
<a class="page-link" href="?page={{ forloop.counter }}">{{ forloop.counter }}</a>
{% endfor %}
{% endblock %}
Но это не работает (ссылки не отображаются). Я думаю, что это потому, что я не прошел контекст, поэтому я изменил последнюю строку выше на
return render(request, 'pagenum_out_of_range.html', status=404,
context=self.get_context_data())
Однако снова появляется ошибка 404 по умолчанию.
Я совершенно запутался по этому поводу. Какой правильный подход?
UPDATE
Очень ценю ваши предложения, и я провел больше исследований и отладок по этому вопросу.
Я попытался переопределить еще несколько методов, упомянутых в Блок-схема метода ListView , чтобы посмотреть, смогу ли я изменить поведение программы или получить некоторые промежуточные результаты.
class MyListView(ListView):
# ...
def get_context_data(self, **kwargs):
print('>>>> get_context_data called')
r = super().get_context_data(**kwargs)
print('>>>> get_context_data return:', r)
return r
def get_template_names(self):
print('>>>> get_template_names called')
r = super().get_template_names()
print('>>>> get_template_names return:', r)
return r
def render_to_response(self, context, **response_kwargs):
print('>>>> render_to_response called')
r = super().render_to_response(context, **response_kwargs)
print('>>>> render_to_response return:', r)
return r
Когда я обновляю страницу, я вижу следующий вывод
>>>> get_context_data called
>>>> get_context_data called
Похоже, что get_context_data
прервано каким-то исключением, и это исключение Http404
поднято с MultipleObjectMixin.paginate_queryset
, как я проследил. Я думаю, это то, где я должен исправить.
Меня беспокоит, что я не могу найти официальную документацию о paginate_queryset
, поэтому я не совсем уверен, что это правильный путь.