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

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

完全按照此处找到的教程进行操作,我无法创建自定义的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中,那是导致问题的原因

Following the tutorial found here exactly, I cannot create a custom 500 or 404 error page. If I do type in a bad url, the page gives me the default error page. Is there anything I should be checking for that would prevent a custom page from showing up?

File directories:

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

within mysite/settings.py I have these enabled:

DEBUG = False
TEMPLATE_DEBUG = DEBUG

#....

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

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

I can post any other code necessary, but what should I be changing to get a custom 500 error page if I use a bad url?

Edit

SOLUTION: I had an additional

TEMPLATE_DIRS

within my settings.py and that was causing the problem


回答 0

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

Under your main views.py add your own custom implementation of the following two views, and just set up the templates 404.html and 500.html with what you want to display.

With this solution, no custom code needs to be added to urls.py

Here’s the code:

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

Update

handler404 and handler500 are exported Django string configuration variables found in django/conf/urls/__init__.py. That is why the above config works.

To get the above config to work, you should define the following variables in your urls.py file and point the exported Django variables to the string Python path of where these Django functional views are defined, like so:

# project/urls.py

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

Update for Django 2.0

Signatures for handler views were changed in Django 2.0: https://docs.djangoproject.com/en/2.0/ref/views/#error-views

If you use views as above, handler404 will fail with message:

“handler404() got an unexpected keyword argument ‘exception'”

In such case modify your views like this:

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

回答 1

官方回答:

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

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才能起作用,否则,将使用常规的调试处理程序。

Official answer:

Here is the link to the official documentation on how to set up custom error views:

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

It says to add lines like these in your URLconf (setting them anywhere else will have no effect):

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'

You can also customise the CSRF error view by modifying the setting CSRF_FAILURE_VIEW.

Default error handlers:

It’s worth reading the documentation of the default error handlers, page_not_found, server_error, permission_denied and bad_request. By default, they use these templates if they can find them, respectively: 404.html, 500.html, 403.html, and 400.html.

So if all you want to do is make pretty error pages, just create those files in a TEMPLATE_DIRS directory, you don’t need to edit URLConf at all. Read the documentation to see which context variables are available.

In Django 1.10 and later, the default CSRF error view uses the template 403_csrf.html.

Gotcha:

Don’t forget that DEBUG must be set to False for these to work, otherwise, the normal debug handlers will be used.


回答 2

将这些行添加到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

# ...

Add these lines in 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'

# ...

and implement our custom views in 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

# ...

回答 3

从您引用的页面:

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

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

handler404 = 'views.my_404_view'

和handler500类似。

From the page you referenced:

When you raise Http404 from within a view, Django will load a special view devoted to handling 404 errors. It finds it by looking for the variable handler404 in your root URLconf (and only in your root URLconf; setting handler404 anywhere else will have no effect), which is a string in Python dotted syntax – the same format the normal URLconf callbacks use. A 404 view itself has nothing special: It’s just a normal view.

So I believe you need to add something like this to your urls.py:

handler404 = 'views.my_404_view'

and similar for handler500.


回答 4

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

If all you need is to show custom pages which have some fancy error messages for your site when DEBUG = False, then add two templates named 404.html and 500.html in your templates directory and it will automatically pick up this custom pages when a 404 or 500 is raised.


回答 5

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

In Django 2.* you can use this construction in views.py

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

In settings.py

DEBUG = False

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

if DEBUG is True:
    ALLOWED_HOSTS = []

In urls.py

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

Usually i creating default_app and handle site-wide errors, context processors in it.


回答 6

settings.py:

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

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

settings.py:

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

and just add your 404.html and 500.html pages in templates folder. remove 404.html and 500.html from templates in polls app.


回答 7

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

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

希望这个帮助!

Make an error, On the error page find out from where django is loading templates.I mean the path stack.In base template_dir add these html pages 500.html , 404.html. When these errors occur the respective template files will be automatically loaded.

You can add pages for other error codes too, like 400 and 403.

Hope this help !!!


回答 8

在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

In Django 3.x, the accepted answer won’t work because render_to_response has been removed completely as well as some more changes have been made since the version the accepted answer worked for.

Some other answers are also there but I’m presenting a little cleaner answer:

In your main urls.py file:

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

In yourapp/views.py file:

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

Ensure that you have imported render() in yourapp/views.py file:

from django.shortcuts import render

Side note: render_to_response() was deprecated in Django 2.x and it has been completely removed in verision 3.x.


回答 9

作为一行(对于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)

As one single line (for 404 generic page):

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)

回答 10

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

# 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' 

This works on django 2.0

Be sure to include your custom 404.html inside the app templates folder.


回答 11

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(重新启动服务器并收集新文件)。

Django 3.0

here is link how to customize error views

here is link how to render a view

in the urls.py (the main one, in project folder), put:

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'

and in that app (my_app_name) put in the 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", {})

NOTE: error/404.html is the path if you place your files into the projects (not the apps) template foldertemplates/errors/404.html so please place the files where you want and write the right path.

NOTE 2: After page reload, if you still see the old template, change in settings.py DEBUG=True, save it, and then again to False (to restart the server and collect the new files).


回答 12

不需要其他视图。https://docs.djangoproject.com/zh-CN/3.0/ref/views/

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

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

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

No additional view is required. https://docs.djangoproject.com/en/3.0/ref/views/

Just put the error files in the root of templates directory

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

And it should use your error page when debug is False


回答 13

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

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

Try moving your error templates to .../Django/mysite/templates/ ?

I’m note sure about this one, but i think these need to be “global” to the website.