Django 3.x — Пользовательская страница ошибок показывает 500, когда должна быть 404

#python #django #cs50

Вопрос:

ОБНОВЛЕНИЕ: Добавлен код, к которому я обращался, который выдал ошибку

Для проекта CS50, над которым я работаю с вики-страницей, я пытаюсь отправить правильную пользовательскую ошибку 404, когда пользователь вводит страницу, которой нет в вики/ЗАГОЛОВКЕ, однако, когда я вводлю отсутствующую страницу, Django выдает 500 вместо 404. Это распространенная ошибка или я ошибся в своем сообщении об ошибке? Для отладки установлено значение False, а Разрешенные хосты настроены на [‘*’] в настройках:

Вот мои пользовательские обработчики ошибок в views.py:

 def error_404(request, exception):
    context = {}
    response = render(request, 'encyclopedia/error_404.html', context=context)
    response.status_code = 404
    return response


def error_500(request):
    context = {}
    response = render(request, 'encyclopedia/error_500.html', context=context)
    response.status_code = 500
    return response
 

Вот как они находятся в wiki/urls.py:

 from django.contrib import admin
from django.urls import include, path
from django.conf.urls import handler404, handler500

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("encyclopedia.urls")),
]

handler404 = "encyclopedia.views.error_404"
handler500 = "encyclopedia.views.error_500"
 

вот функция в views.py что я получаю доступ, но собираюсь перейти на wiki/C:

 #function gets entry from index.html's <li>
def entry_page(request, entry):
    name = entry                     # Places the title       
    print(f"checking the title: {entry}")                            
    text = util.get_entry(entry)     # Grabs the entry using the util function
    html = md_converter(text)  

    if text is not None:
        return render(request, "encyclopedia/entry.html", {
            "title": name,
            "entry": html
        })
 

И вот мой urls.py для хорошей меры:

 from django.urls import path

from . import views

app_name = "encyclopedia"
urlpatterns = [
    path("", views.index, name="index"),
    path("wiki/<str:entry>", views.entry_page, name="entry"),
    path("wiki/edit/<str:title>", views.edit, name="edit"),
    path("search", views.search, name="search"),
    path("random", views.random_page, name="random"),
    path("create_entry",views.create_entry, name="create_entry")
]
 

Вот что показывает терминал (мой styles.css по какой-то причине выдает 404, но я там ничего не изменил…это отдельная проблема):
мой терминал, когда я перехожу на страницу, которой там нет

Комментарии:

1. установите DEBUG=True и попробуйте получить доступ к странице. Вы увидите, что не так в /wiki/C

2. Эта страница-всего лишь пример для запуска ошибки, DEBUG True показывает 404 просто отлично. Я тестирую функциональность ошибки 404 с настройкой ОТЛАДКИ на false

3. Изменение его на true и ввод ложного URL-адреса выдает: «декодирование в str: нужен байтоподобный объект, не найден тип». Это что-нибудь значит?

4. Да, это исключение/ошибка, и поэтому он должен показывать 500 страниц, а не 404

5. 500 означает, что ваша программа испортилась. Не выключайте режим отладки, пока не устраните причину исключения. Вы не предоставили ту часть исходного кода, которая вызывает ошибку, поэтому мы не можем помочь вам в дальнейшем. Когда ваш код поймет, что пользователь пытается получить доступ к несуществующей странице (из-за вашей ошибки, вероятно, используя что-то подобное if foo is None ), вызовите django.http.Http404 .

Ответ №1:

Возможно, с вашим кодом что-то не так. Джанго док четко говорит

 The 404 view is also called if Django doesn’t find a match after checking every regular expression in the URLconf.
 

https://docs.djangoproject.com/en/3.2/ref/views/#error-views

Ответ №2:

Понял это. Спасибо тебе.

В функции, которую я использовал для захвата страницы, произошла ошибка. Я не проверял, действителен ли URL-адрес при поиске конкретной записи вики.

Изменение страницы входа в views.py чтобы это сработало!:

 def entry_page(request, entry):                              
if entry in util.list_entries():
    name = entry                     # Places the title    
    text = util.get_entry(entry)     # Grabs the entry using the util function
    html = md_converter(text)  
    return render(request, "encyclopedia/entry.html", {
        "title": name,
        "entry": html
    })
else:  
        return render(request, "encyclopedia/error_404.html" )
 

Рад, что это не Джанго все испортил, только я, лол

Комментарии:

1. return render(req, template) просто рисует страницу 404, но на самом деле не возвращает статус 404. Если клиент смотрит на код статуса, он подумает, что все в порядке, так как он получает 200 ОК (с некоторым текстом). Либо обязательно верните правильный код состояния с помощью return render(req, template, status=404) , либо, предпочтительно, вызовите Http404 исключение быстрого доступа, которое я показал выше. Вот учебник по Django , в котором показано, как это сделать правильно.

2. Ах, в этом еще больше смысла. Я отредактирую код, чтобы отразить это