128

完全按照此处找到的教程,我无法创建自定义 500 或 404 错误页面。如果我确实输入了错误的 url,该页面会给我默认的错误页面。有什么我应该检查的东西会阻止自定义页面出现吗?

文件目录:

mysite/
    mysite/
        __init__.py
        __init__.pyc
        settings.py
        settings.pyc
        urls.py
        urls.pyc
        wsgi.py
        wsgi.pyc
    polls/
        templates/
            admin/
                base_site.html
            404.html
            500.html
            polls/
                detail.html
                index.html
        __init__.py
        __init__.pyc
        admin.py
        admin.pyc
        models.py
        models.pyc
        tests.py
        urls.py
        urls.pyc
        view.py
        views.pyc
    templates/
    manage.py

在 mysite/settings.py 我启用了这些:

DEBUG = False
TEMPLATE_DEBUG = DEBUG

#....

TEMPLATE_DIRS = (
    'C:/Users/Me/Django/mysite/templates', 
)

在 mysite/polls/urls.py 中:

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
    url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)

我可以发布任何其他必要的代码,但是如果我使用错误的 url,我应该改变什么以获得自定义的 500 错误页面?

编辑

解决方案: 我有一个额外的

TEMPLATE_DIRS

在我的 settings.py 中,这导致了问题

4

15 回答 15

135

在您的 main 下添加您自己的以下两个视图的自定义实现,并使用您想要显示的内容views.py设置模板404.html500.html 。

使用此解决方案,无需添加自定义代码urls.py

这是代码:

from django.shortcuts import render_to_response
from django.template import RequestContext


def handler404(request, *args, **argv):
    response = render_to_response('404.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 404
    return response


def handler500(request, *args, **argv):
    response = render_to_response('500.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 500
    return response

更新

handler404并且handler500是导出的 Django 字符串配置变量,位于django/conf/urls/__init__.py. 这就是上述配置有效的原因。

要使上述配置正常工作,您应该在urls.py文件中定义以下变量,并将导出的 Django 变量指向定义这些 Django 功能视图的字符串 Python 路径,如下所示:

# project/urls.py

handler404 = 'my_app.views.handler404'
handler500 = 'my_app.views.handler500'

Django 2.0 更新

处理程序视图的签名在 Django 2.0 中已更改: https ://docs.djangoproject.com/en/2.0/ref/views/#error-views

如果您使用上述视图,handler404 将失败并显示以下消息:

“handler404() 得到了一个意外的关键字参数‘异常’”

在这种情况下,像这样修改您的视图:

def handler404(request, exception, template_name="404.html"):
    response = render_to_response(template_name)
    response.status_code = 404
    return response
于 2014-07-13T16:56:52.610 回答
93

官方回答:

这是有关如何设置自定义错误视图的官方文档的链接:

https://docs.djangoproject.com/en/stable/topics/http/views/#customizing-error-views

它说在你的 URLconf 中添加这样的行(将它们设置在其他任何地方都没有效果):

handler404 = 'mysite.views.my_custom_page_not_found_view'
handler500 = 'mysite.views.my_custom_error_view'
handler403 = 'mysite.views.my_custom_permission_denied_view'
handler400 = 'mysite.views.my_custom_bad_request_view'

您还可以通过修改设置自定义 CSRF 错误视图CSRF_FAILURE_VIEW

默认错误处理程序:

值得阅读默认错误处理程序page_not_foundserver_errorpermission_deniedbad_request. 默认情况下,如果他们能找到这些模板,他们将分别使用它们:404.html500.html403.html400.html

因此,如果您只想制作漂亮的错误页面,只需在TEMPLATE_DIRS目录中创建这些文件,您根本不需要编辑 URLConf。阅读文档以查看可用的上下文变量。

在 Django 1.10 及更高版本中,默认的 CSRF 错误视图使用模板403_csrf.html

明白了:

不要忘记DEBUG必须设置为 False 才能使这些工作,否则将使用正常的调试处理程序。

于 2016-06-03T09:52:12.830 回答
51

在 urls.py 中添加这些行

网址.py

from django.conf.urls import (
handler400, handler403, handler404, handler500
)

handler400 = 'my_app.views.bad_request'
handler403 = 'my_app.views.permission_denied'
handler404 = 'my_app.views.page_not_found'
handler500 = 'my_app.views.server_error'

# ...

并在views.py 中实现我们的自定义视图。

视图.py

from django.shortcuts import (
render_to_response
)
from django.template import RequestContext

# HTTP Error 400
def bad_request(request):
    response = render_to_response(
        '400.html',
        context_instance=RequestContext(request)
        )

        response.status_code = 400

        return response

# ...
于 2015-10-26T10:03:48.697 回答
28

Django 3.0+ 4.0+

这是如何自定义错误视图的链接

这是链接如何呈现视图

urls.py(主要的,在项目文件夹中)中,放入:

handler404 = 'my_app_name.views.custom_page_not_found_view'
handler500 = 'my_app_name.views.custom_error_view'
handler403 = 'my_app_name.views.custom_permission_denied_view'
handler400 = 'my_app_name.views.custom_bad_request_view'

并在提到的应用程序(my_app_name)中放入views.py

def custom_page_not_found_view(request, exception):
    return render(request, "errors/404.html", {})

def custom_error_view(request, exception=None):
    return render(request, "errors/500.html", {})

def custom_permission_denied_view(request, exception=None):
    return render(request, "errors/403.html", {})

def custom_bad_request_view(request, exception=None):
    return render(request, "errors/400.html", {})

注意:errors/404.html如果您将文件放入项目(而不是应用程序)模板文件夹中,则为路径,templates/errors/404.html因此请将文件放置在您想要的位置并编写正确的路径。

注意2:页面重新加载后,如果您仍然看到旧模板,请更改settings.py DEBUG=True,保存,然后再次False保存并再次保存(这将重新启动服务器并收集新文件)。

于 2020-03-31T20:00:37.350 回答
23

从您引用的页面:

当您从视图中引发 Http404 时,Django 将加载一个专用于处理 404 错误的特殊视图。它通过在您的根 URLconf 中查找变量 handler404 来找到它(并且仅在您的根 URLconf 中;在其他任何地方设置 handler404 将无效),它是 Python 点分语法中的字符串 - 与普通 URLconf 回调使用的格式相同。404 视图本身并没有什么特别之处:它只是一个普通视图。

所以我相信你需要在你的 urls.py 中添加这样的东西:

handler404 = 'views.my_404_view'

和 handler500 类似。

于 2013-07-15T20:13:47.010 回答
19

如果您只需要显示自定义页面,其中包含一些花哨的错误消息,请DEBUG = False在模板目录中添加两个名为 404.html 和 500.html 的模板,当出现 404 或 500 时,它将自动选择此自定义页面被提出。

于 2016-12-01T04:54:55.200 回答
16

在 Django3.x中,接受的答案将不起作用,因为render_to_response已完全删除,并且自接受的答案适用的版本以来已经进行了一些更改。

其他一些答案也在那里,但我提出了一个更清晰的答案:

在您的主urls.py文件中:

handler404 = 'yourapp.views.handler404'
handler500 = 'yourapp.views.handler500'

yourapp/views.py文件中:

def handler404(request, exception):
    context = {}
    response = render(request, "pages/errors/404.html", context=context)
    response.status_code = 404
    return response


def handler500(request):
    context = {}
    response = render(request, "pages/errors/500.html", context=context)
    response.status_code = 500
    return response

确保您已导入render()文件yourapp/views.py

from django.shortcuts import render

旁注:render_to_response()在 Django 中已弃用,在2.x版本中已完全删除3.x

于 2020-02-20T11:19:18.167 回答
15

不需要额外的视图。https://docs.djangoproject.com/en/3.0/ref/views/

只需将错误文件放在模板目录的根目录中即可

  • 404.html
  • 400.html
  • 403.html
  • 500.html

当 debug 为 False 时,它​​应该使用您的错误页面

于 2020-05-19T13:10:26.963 回答
14

Django 2.*中,您可以在views.py中使用此构造

def handler404(request, exception):
    return render(request, 'errors/404.html', locals())

settings.py

DEBUG = False

if DEBUG is False:
    ALLOWED_HOSTS = [
        '127.0.0.1:8000',
        '*',
    ]

if DEBUG is True:
    ALLOWED_HOSTS = []

urls.py

# https://docs.djangoproject.com/en/2.0/topics/http/views/#customizing-error-views
handler404 = 'YOUR_APP_NAME.views.handler404'

通常我创建default_app并在其中处理站点范围的错误、上下文处理器。

于 2018-02-26T08:38:43.480 回答
14

设置.py:

DEBUG = False
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = ['localhost']  #provide your host name

只需在模板文件夹中添加您的404.html500.html页面。从民意调查应用程序中的模板中删除404.html和删除。500.html

于 2016-03-03T10:58:01.140 回答
7

出错,在错误页面上找出 django 从哪里加载模板。我的意思是路径堆栈。在基本模板目录中添加这些 html 页面500.html404.html。发生这些错误时,将自动加载相应的模板文件。

您也可以为其他错误代码添加页面,例如400403

希望这有帮助!

于 2016-08-17T09:42:39.617 回答
5

作为一行(对于 404 通用页面):

from django.shortcuts import render_to_response
from django.template import RequestContext

return render_to_response('error/404.html', {'exception': ex},
                                      context_instance=RequestContext(request), status=404)
于 2015-05-04T13:07:33.583 回答
5
# views.py
def handler404(request, exception):
    context = RequestContext(request)
    err_code = 404
    response = render_to_response('404.html', {"code":err_code}, context)
    response.status_code = 404
    return response

# <project_folder>.urls.py
handler404 = 'todo.views.handler404' 

这适用于 django 2.0

确保将您的自定义包含404.html在应用程序模板文件夹中。

于 2018-06-30T07:58:28.710 回答
3

尝试将您的错误模板移动到.../Django/mysite/templates/?

我很确定这一点,但我认为这些需要对网站来说是“全球性的”。

于 2013-07-15T20:16:50.217 回答
0

在 Django 根 urls.py 文件中,添加以下行

from django.conf.urls import (handler400, handler403, handler404, handler500)

handler400 = 'app.views.bad_request'
handler403 = 'app.views.permission_denied'
handler404 = 'app.views.page_not_found'
handler500 = 'app.views.server_error'

在您应用的 views.py 文件中,创建相应的函数。

def server_error(request, exception=None):
    # return render(request, '500.html')
    return redirect('/')

最后,在你的 settings.py 文件中,设置DEBUG = False

于 2022-01-28T07:12:18.237 回答