【问题标题】:Django HTTP 500 ErrorDjango HTTP 500 错误
【发布时间】:2013-02-06 14:55:39
【问题描述】:

我正在创建自定义 HTTP 500 错误模板。为什么 Django 在我引发异常而不是在我返回 HttpResponseServerError 时显示它(我只是得到默认浏览器 500 错误)?我觉得这种行为很奇怪......

【问题讨论】:

    标签: python django http templates


    【解决方案1】:

    HttpResponseServerError 继承自 HttpResponse,实际上非常简单:

    class HttpResponseServerError(HttpResponse):
        status_code = 500
    

    那么让我们看看HttpResponse构造函数:

    def __init__(self, content='', *args, **kwargs):
        super(HttpResponse, self).__init__(*args, **kwargs)
        # Content is a bytestring. See the `content` property methods.
        self.content = content
    

    你可以看到默认content是空的。

    现在,让我们看看它是如何被 Django 自己调用的(摘自 django.views.defaults):

    def server_error(request, template_name='500.html'):
        """
        500 error handler.
    
        Templates: :template:`500.html`
        Context: None
        """
        try:
            template = loader.get_template(template_name)
        except TemplateDoesNotExist:
            return http.HttpResponseServerError('<h1>Server Error (500)</h1>')
        return http.HttpResponseServerError(template.render(Context({})))
    

    正如您所看到的,当您产生服务器错误时,使用了名为 500.html 的模板,但是当您简单地返回 HttpResponseServerError 时,内容为空,浏览器将退回到它的默认页面。

    【讨论】:

    • 感谢您的分析。那么在这种情况下,正确的约定是什么?将我的模板传递给 HttpResponseServerError?还是只是为了引发异常?
    • 出于几个原因,我更愿意提出例外。首先,您可以利用 Django 中间件机制(查看docs.djangoproject.com/en/dev/topics/http/middleware/…)并添加一些日志记录和特定异常的处理等,其次您可以编写自己的自定义 500 视图(docs.djangoproject.com/en/dev/topics/http/views/…)。
    • 第三,500 表示内部服务器错误,也就是说 - 确实搞砸了。在一个你唯一能做的处理就是说“好吧,是的,事情真的搞砸了”的地方处理这个是没有意义的。让错误遵循它的自然路径,如果你不能正确处理它,让 Django 为你处理它。
    【解决方案2】:

    把它放在 urls.py 的下面。

    #handle the errors    
    from django.utils.functional import curry
    from django.views.defaults import *
    
    handler500 = curry(server_error, template_name='500.html')
    

    将 500.html 放入您的模板中。就这么简单。

    【讨论】:

      【解决方案3】:

      您是否尝试过使用其他浏览器?您的自定义错误页面是否大于 512 字节?当服务器的答案短于 512 字节时,似乎某些浏览器(包括 Chrome)会用自己的错误页面替换错误页面。

      【讨论】:

      • 奇怪.. 当我返回 HttpResponseServerError 时它可以工作,但是当我返回 HttpResponseServerError() 时它不会。有括号不是正确的吗?
      【解决方案4】:

      从 Django 2+ 开始,您只需将相应的错误模板放在基本模板文件夹中即可。 Django 会在呈现默认值之前自动呈现它们。

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

      在您的情况下,只需将模板“500.html”(或“404.html”)放入 /templates

      【讨论】:

        猜你喜欢
        • 2020-02-04
        • 2016-05-18
        • 1970-01-01
        • 2018-02-28
        • 1970-01-01
        • 2018-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多