【问题标题】:How to obtain a plain text Django error page如何获取纯文本 Django 错误页面
【发布时间】:2011-02-07 12:16:04
【问题描述】:

在开发过程中,我在调试模式下运行 Django,并使用文本模式应用程序将数据发布到我的应用程序。理想情况下,当我收到 http 错误代码 500 时,我需要收到纯文本响应,这样我就不必在所有 HTML 和 Javascript 中寻找真正的错误。

是否可以获得纯文本形式的 Django 500 内部服务器错误?

【问题讨论】:

标签: python django http


【解决方案1】:

如果您正在寻找一种在使用 curl 时获取纯文本错误页面的方法,您 需要添加HTTP头X-Requested-With,值为XMLHttpRequest,例如

curl -H 'X-Requested-With: XMLHttpRequest' http://example.com/some/url/

解释:这是因为 Django 使用is_ajax 方法来确定是返回纯文本还是 HTML。 is_ajax 反过来看X-Requested-With


更新

从 django 3.1 版开始,错误报告会忽略 X-Requested-With 标头。相反,请将请求上的 Accept 标头设置为任何包含text/html mime 类型的有效值。

例如

curl -H 'Accept: application/json;charset=utf-8' http://example.comp/some/url

【讨论】:

  • 在 2020 年,使用带有一些包含“text/html”的值的“Accept”标头
【解决方案2】:

这是对 Yuji 答案的改进,它提供了堆栈跟踪、更多说明(对于我们 django 新手而言)并且更简单。

将此代码放在应用程序某处的文件中,例如PROJECT_ROOT/MAIN_APP/middleware/exceptions.py,并确保在同一目录中有一个空的__init__.py

import traceback
from django.http import HttpResponse

class PlainExceptionsMiddleware(object):
    def process_exception(self, request, exception):
        return HttpResponse(traceback.format_exc(exception), content_type="text/plain", status=500)

现在编辑您的settings.py 并找到MIDDLEWARE_CLASSES = (。添加另一个条目,如下所示:

MIDDLEWARE_CLASSES = (
    # (all the previous entries)

    # Plain text exception pages.
    'MAIN_APP.middleware.exceptions.PlainExceptionsMiddleware',
)

重新启动 django,一切顺利!

用户代理感知格式。

如果您像我一样开发由 django 支持的应用程序和网站,您可能希望向应用程序显示纯文本错误页面,并向浏览器显示格式良好的错误页面。一个简单的方法是检查用户代理:

import traceback
from django.http import HttpResponse

class PlainExceptionsMiddleware(object):
    def process_exception(self, request, exception):
        if "HTTP_USER_AGENT" in request.META and "chrome" in request.META["HTTP_USER_AGENT"].lower():
            return
        return HttpResponse(traceback.format_exc(exception), content_type="text/plain", status=500)

【讨论】:

  • 在 Django 2.0 中删除了对 MIDDLEWARE_CLASSES 的支持。
  • 现在的中间件类,需要添加方法def __init__(self, get_response): self.get_response = get_response
  • 这个中间件仍然返回 HTML。看来,即使你调用traceback.format_exc(exception)process_exception 的其余部分也不会运行,因此异常会像往常一样以 HTML 形式返回。
  • 如果你只做traceback.format_exc(),而不是传入exception,它就可以正常工作
【解决方案3】:

我想写个中间件,否则500.html中没有异常

http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception

class ProcessExceptionMiddleware(object):
    def process_exception(self, request, exception):
        t = Template("500 Error: {{ exception }}")
        response_html = t.render(Context({'exception' : exception }))

        response = http.HttpResponse(response_html)
        response.status_code = 500
        return response

【讨论】:

  • 这行得通,谢谢。现在的问题是访问堆栈跟踪,因为“异常”只是一个常规的异常对象。
  • 恭喜!查看sys.exc_info() 以访问回溯。我建议直接查看在django.core.handlers.base 中通常执行回溯格式化的 django 代码以实现您自己的版本。
  • @Dmitry 的回答更好,恕我直言。
【解决方案4】:

有一个设置 DEBUG_PROPAGATE_EXCEPTIONS 将强制 Django 不包装异常,因此您可以看到它们,例如在开发服务器日志中。

【讨论】:

【解决方案5】:

Timmmm's answer 的基础上,我必须对其进行一些修改才能在 Django 3.1 中工作:

在应用程序的某处创建一个文件,例如 YOUR_APP_NAME/middleware/exceptions.py 并粘贴以下代码:

import traceback
from django.http import HttpResponse, HttpRequest

class PlainExceptionsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        return self.get_response(request)

    def process_exception(self, request: HttpRequest, exception: Exception):
        if "HTTP_USER_AGENT" in request.META and "chrome" in request.META["HTTP_USER_AGENT"].lower():
            return
        print(traceback.format_exc())
        return HttpResponse(repr(exception), content_type="text/plain", status=500)

不必在middleware 文件夹中创建__init__.py 文件。

settings.py 中,将以下项添加到 MIDDLEWARE 变量的末尾,使其看起来像:

MIDDLEWARE = [
    # ...
    'YOUR_APP_NAME.middleware.exceptions.PlainExceptionsMiddleware'
]

现在,如果“HTTP_USER_AGENT”和“chrome”在请求头中,这个中间件不会做任何事情,所以 Django 像往常一样返回一个 HTML 响应。否则,它会返回错误的纯文本表示形式作为响应(例如,ValueError("Field 'id' expected a number but got 'undefined'."))并像 Django 通常那样将回溯打印到 Django 控制台。当然,您可以改为返回完整的回溯作为您的响应。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2023-03-08
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 2012-05-14
    • 2023-03-26
    相关资源
    最近更新 更多