发送错误Link to this heading

当您运行着公开的网页时,你应该把设置中的 DEBUG 选项设为关闭。 这将使您的服务器运行得更快,并且还可以防止恶意用户在错误页面中看到应用的详细信息。

However, running with DEBUG set to False means you'll never see errors generated by your site -- everyone will instead see your public error pages. You need to keep track of errors that occur in deployed sites, so Django can be configured to create reports with details about those errors.

通过邮件方式报告Link to this heading

服务器错误Link to this heading

DEBUGFalse 时,Django 会在代码抛出的异常未被捕获且导致一个内部的服务器错误(HTTP 状态码 500)时向 ADMINS 配置中列出的用户发送邮件。这让管理员立刻收到错误通知。 ADMINS 列表中的用户,会收到详细的错误描述,完整的 Python 调用栈,和引发此错误的 HTTP 请求的细节。

默认情况下,Django 会从 root@localhost 发送邮件。然而,某些邮件服务商拒绝来自该地址的所有邮件。要使用不同的发件人地址,修改 SERVER_EMAIL 配置。

要启动该行为,将收件人的邮箱地址放入 ADMINS

404 错误Link to this heading

Django 也能配置成为已失效的连接发送错误邮件(404 "page not found" 错误)。Django 发送 404 错误邮件的条件:

If those conditions are met, Django will email the users listed in the MANAGERS setting whenever your code raises a 404 and the request has a referer. It doesn't bother to email for 404s that don't have a referer -- those are usually people typing in broken URLs or broken Web bots. It also ignores 404s when the referer is equal to the requested URL, since this behavior is from broken Web bots too.

你可以通过调整配置项 IGNORABLE_404_URLS 让 Django 忽略某些 404s。内容应该是已编译的正则表达式的列表。例子:

Code
import re
IGNORABLE_404_URLS = [
    re.compile(r'\.(php|cgi)$'),
    re.compile(r'^/phpmyadmin/'),
]

在本例中,对以 .php.cgi 结尾的 URL 的 404 错误将 不会 被报告。以 phpmyadmin 开头的也不会被报告。

下面的例子展示了如何排除一些浏览器和爬虫经常访问的传统 URL:

Code
import re
IGNORABLE_404_URLS = [
    re.compile(r'^/apple-touch-icon.*\.png$'),
    re.compile(r'^/favicon\.ico$'),
    re.compile(r'^/robots\.txt$'),
]

(注意,这些都是正则表达式,所以我们用反斜杠转义了点号。)

若后续你想自定义 django.middleware.common.BrokenLinkEmailsMiddleware 的行为(例如忽略来自网络爬虫的请求),你需要继承该类,并重写方法。

过滤错误报告Link to this heading

过滤敏感数据Link to this heading

错误报告对于调试错误来说超级有用,所以通常尽可能多的记录关键信息。例如,Django 默认记录了抛出异常的 完整调用栈,每个 调用栈层 的局部变量,以及 HttpRequest属性

然而,有时候某些信息会涉及敏感内容,因此不适合写入调用栈。例如,用户的密码或信用卡号。故此,为了过滤 DEBUG 文档中描述的敏感内容,Django 提供了一系列的函数装饰器,帮你控制在生产环境(即 DEBUGFalse)下应该从错误报告中过滤掉哪些信息:sensitive_variables()sensitive_post_parameters()

sensitive_variables(*variables)Link to this definition

若代码中的一个函数(也可能是视图或定期回调)使用容易包含敏感信息的本地变量,你可以用 sensitive_variables 装饰器阻止错误报告包含这些变量的值:

Code
from django.views.decorators.debug import sensitive_variables

@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
    pw = user.pass_word
    cc = user.credit_card_number
    name = user.name
    ...

In the above example, the values for the user, pw and cc variables will be hidden and replaced with stars (**********) in the error reports, whereas the value of the name variable will be disclosed.

要在错误日志中系统的隐藏所有的局部变量,不要向 sensitive_variables 装饰器传入任何参数:

Code
@sensitive_variables()
def my_function():
    ...
sensitive_post_parameters(*parameters)Link to this definition

若视图收到一个包含 POST 参数HttpRequest 对象,参数中极有可能内含敏感信息。你可以通过 sensitive_post_parameters 装饰器避免这些参数的值被包括在错误报告中:

Code
from django.views.decorators.debug import sensitive_post_parameters

@sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
    UserProfile.create(
        user=request.user,
        password=request.POST['pass_word'],
        credit_card=request.POST['credit_card_number'],
        name=request.POST['name'],
    )
    ...

In the above example, the values for the pass_word and credit_card_number POST parameters will be hidden and replaced with stars (**********) in the request's representation inside the error reports, whereas the value of the name parameter will be disclosed.

要在错误报告中系统的屏蔽所有 POST 参数,不要给 sensitive_post_parameters 装饰器提供任何参数:

Code
@sensitive_post_parameters()
def my_view(request):
    ...

为了避免敏感信息的泄露(例如账号密码), 所有传入认证视图 django.contrib.auth.viewsloginpassword_reset_confirmpassword_change, and add_viewauth 后台中的 user_change_password)的 POST 参数都在错误报告中经过系统过滤。

自定义错误报告Link to this heading

All sensitive_variables() and sensitive_post_parameters() do is, respectively, annotate the decorated function with the names of sensitive variables and annotate the HttpRequest object with the names of sensitive POST parameters, so that this sensitive information can later be filtered out of reports when an error occurs. The actual filtering is done by Django's default error reporter filter: django.views.debug.SafeExceptionReporterFilter. This filter uses the decorators' annotations to replace the corresponding values with stars (**********) when the error reports are produced. If you wish to override or customize this default behavior for your entire site, you need to define your own filter class and tell Django to use it via the DEFAULT_EXCEPTION_REPORTER_FILTER setting:

Code
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'

你也能在任意视图内以一种更细碎的方式控制过滤器,通过设置 HttpRequestexception_reporter_filter 属性:

Code
def my_view(request):
    if request.user.is_authenticated:
        request.exception_reporter_filter = CustomExceptionReporterFilter()
    ...

自定义过滤器类需要继承自 django.views.debug.SafeExceptionReporterFilter 并重写以下方法:

class SafeExceptionReporterFilterLink to this definition
SafeExceptionReporterFilter.is_active(request)Link to this definition

返回 True 将激活其它方法中的过滤操作。 DEBUGFalse 时,过滤器默认是激活的。

SafeExceptionReporterFilter.get_post_parameters(request)Link to this definition

Returns the filtered dictionary of POST parameters. By default it replaces the values of sensitive parameters with stars (**********).

SafeExceptionReporterFilter.get_traceback_frame_variables(request, tb_frame)Link to this definition

Returns the filtered dictionary of local variables for the given traceback frame. By default it replaces the values of sensitive variables with stars (**********).