Django,创建自定义500/404错误页面


105

完全按照此处找到的教程进行操作,我无法创建自定义的500或404错误页面。如果我确实输入了错误的网址,则该页面会显示默认的错误页面。我应该检查哪些内容以防止显示自定义页面?

文件目录:

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'),
)

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

编辑

解决方案: 我还有一个

TEMPLATE_DIRS

在我的settings.py中,那是导致问题的原因


1
在我的代码中,将Debug设置为False
Zac


1
在寻找仅制作自定义模板的方法时找到了这个答案,我想分享一些Django文档,这对我有很大帮助;docs.djangoproject.com/en/1.7/ref/views/…– Blackeagle52
2014年

我的工作没有template_dirs设置。
Programmingjoe

1
当第一行链接指向Django 404页面时,具有讽刺意味的要点。导致我认为不存在的Django版本的教程页面。以下是Django 2.0教程页面的链接:docs.djangoproject.com/en/2.0/intro/tutorial03
andrewec

Answers:


120

在您的主目录下,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

更新资料

handler404handler500导出的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()获得了意外的关键字参数'exception'”

在这种情况下,请修改您的视图,如下所示:

def handler404(request, exception, template_name="404.html"):
    response = render_to_response(template_name)
    response.status_code = 404
    return response

这对我来说似乎工作得很好,但是出于某种原因,request.user在404模板中看起来不错,但在500模板中根本就不行(它们几乎完全相同)—在此处发布问题:stackoverflow.com/ Questions / 26043211 /…
重力Grave

1
我想知道的另一件事-如果您使用管理后端并想为它们使用单​​独的模板怎么办?据我所知,管理员没有一个views.py覆盖,并把这段代码英寸
重力墓

11
@GravityGrave 500 template不会渲染,request.user因为它报告了500个服务器错误,因此服务器无法提供任何服务。
亚伦·莱里维耶

5
使用django 1.9不能为我工作;((也许我做错了。handler404 django是保留名称吗?django怎么会知道它应该确切地调用该视图?
deathangel908

1
我根据您的评论更新了答案。抱歉,更新太晚了。我希望这个对你有用。
亚伦·莱里维耶

71

官方回答:

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

https://docs.djangoproject.com/zh-CN/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错误视图使用template 403_csrf.html

陷阱:

不要忘记DEBUG必须将它们设置为False才能起作用,否则,将使用常规的调试处理程序。


1
我确实添加了,但是没有用。添加了handler404和其他指向我视图中正确位置的对象,但仍然无法正常工作,仍然看到默认的404。是的,我处于Debug False模式,并使用1.9
KhoPhi

使用Django 1.9并仅添加500.html etc模板即可显示它们,而不是标准页面。很容易修复。
curtisp

2
Gotcha帮助了我。它通过在我的settings.py中进行这些更改来工作,设置DEBUG = False且ALLOWED_HOSTS = ['0.0.0.0']接受来自任何客户端的http请求。
shaffooo

1
万一别人是想知道到底是URL配置,在这里它是
亚瑟·塔拉索夫

38

将这些行添加到urls.py中

urls.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中实现我们的自定义视图。

views.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

# ...

5
为什么handler400只导入以覆盖handler400 = 'myapp.views.bad_request'
Flimm'6


5
您无需在此处导入处理程序即可覆盖它们。
funkotron '16

1
您不应该使用render_to_response。从文档中可以看出:“不建议使用,将来可能会弃用。”
蒂米·奥马洪尼

对于Django 1.10 render_to_response(即将弃用),请参见以下内容(render改用):stackoverflow.com/questions/44228397/…–
mrdaliri

21

从您引用的页面:

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

因此,我相信您需要在urls.py中添加以下内容:

handler404 = 'views.my_404_view'

和handler500类似。


迈克看起来怎么样?今天是我使用Django的第一天,我仍然挂在绳子上
Zac

2
@JimRilye您需要在视图中添加合适的500函数,然后使用该变量引用它。因此,在您的代码urlpatterns = ...行上方,添加一条说为的代码行,handler500 = 'views.handle500'然后将a添加def handle500(request):到显示500.html的views.py中。
Mike Pelley

18

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


1
这项工作只要确保您具有以下内容即可:'DIRS': [os.path.join(BASE_DIR, '<project_name>/templates')]在的TEMPLATES列表中settings.py
eric

12

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并处理站点范围的错误,并在其中处理上下文。


为我工作。但是什么exception呢?
zeleven

根据文档链接:docs.djangoproject.com/en/2.1/ref/urls/…。上面写着:确保处理程序接受请求和异常参数
Alouani Younes 18/12/12

1
Django 3.0中为我工作。但是什么locals()呢?该文件仅显示pass
enchance

9

settings.py:

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

并将您的404.html500.html页面添加到模板文件夹中。删除404.html500.html从模板中投票应用程序。


还提供了如何使用消息raise Http404('msg')stackoverflow.com/a/37109914/895245 {{ request_path }}
西罗桑蒂利郝海东冠状病六四事件法轮功

TEMPLATE_DEBUG已从django2docs.quantifiedcode.com/python-anti-patterns/django/1.8/…中删除
Steve W,

7

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

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

希望这个帮助!


6

在Django中3.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在verision中已完全删除3.x


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)

1
以及在哪里使用?
萨米(Sami)

4
# 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包含在应用程序模板文件夹中。


4

Django 3.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", {})

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

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


额外说明:如果您正在运行DEUB=False静态文件,则可能无法提供服务,因此无法预览自定义错误模板的更改。使用./manage.py runserver --insecuredjango来为他们服务。
Rob


3

尝试将错误模板移至.../Django/mysite/templates/

我注意到这一点,但是我认为这些对于网站来说必须是“全球性的”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.