{"title":"发送错误","version":"2.2","locale":"zh-hans","docname":"howto/error-reporting","url":"/zh-hans/2.2/howto/error-reporting/","canonical":"https://djangodocs.dev/zh-hans/2.2/howto/error-reporting/","summary":"当您运行着公开的网页时，你应该把设置中的 DEBUG 选项设为关闭。 这将使您的服务器运行得更快，并且还可以防止恶意用户在错误页面中看到应用的详细信息。 然而，把 DEBUG 设置为 False，…","html":"<h1>发送错误<a class=\"heading-anchor\" href=\"#error-reporting\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>当您运行着公开的网页时，你应该把设置中的 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> 选项设为关闭。 这将使您的服务器运行得更快，并且还可以防止恶意用户在错误页面中看到应用的详细信息。</p>\n<p>然而，把 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> 设置为 False， 这意味着你永远不会在你的网站上看到错误的细节，所有的人都只是看到你公开的错误页面。当你需要在部署的网页上追踪出现的错误，Django 可以通过设置去报告错误的细节。</p>\n<section id=\"email-reports\">\n<h2>通过邮件方式报告<a class=\"heading-anchor\" href=\"#email-reports\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"server-errors\">\n<h3>服务器错误<a class=\"heading-anchor\" href=\"#server-errors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> is <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>, Django will email the users listed in the\n<a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-ADMINS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ADMINS</span></code></a> setting whenever your code raises an unhandled exception and\nresults in an internal server error (strictly speaking, for any response with\nan HTTP status code of 500 or greater). This gives the administrators immediate\nnotification of any errors. The <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-ADMINS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ADMINS</span></code></a> will get a description of the\nerror, a complete Python traceback, and details about the HTTP request that\ncaused the error.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>要发送邮件，Django 要求一些配置项，告诉它如何连接至邮件服务器。最小配置下，你需要指定 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-EMAIL_HOST\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">EMAIL_HOST</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-EMAIL_HOST_USER\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">EMAIL_HOST_USER</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-EMAIL_HOST_PASSWORD\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">EMAIL_HOST_PASSWORD</span></code></a>，可能还有其它配置，这取决于邮件服务器的配置。查阅 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/\"><span class=\"doc\">Django 配置文档</span></a> 获取邮件相关配置的完整列表。</p>\n</aside>\n<p>默认情况下，Django 会从 <a class=\"reference external\" href=\"mailto:root&#37;&#52;&#48;localhost\">root<span>&#64;</span>localhost</a> 发送邮件。然而，某些邮件服务商拒绝来自该地址的所有邮件。要使用不同的发件人地址，修改 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-SERVER_EMAIL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SERVER_EMAIL</span></code></a> 配置。</p>\n<p>要启动该行为，将收件人的邮箱地址放入 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-ADMINS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ADMINS</span></code></a>。</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<p>服务器错误邮件由 logging 框架发出，所以你能通过 <a class=\"reference internal\" href=\"/zh-hans/2.2/topics/logging/\"><span class=\"doc\">自定义 logging 配置</span></a> 自定义该行为。</p>\n</aside>\n</section>\n<section id=\"errors\">\n<h3>404 错误<a class=\"heading-anchor\" href=\"#errors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 也能配置成为已失效的连接发送错误邮件（404 &quot;page not found&quot; 错误）。Django 发送 404 错误邮件的条件：</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> 为 <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>；</p></li>\n<li><p><a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> 配置包括 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/middleware/#django.middleware.common.BrokenLinkEmailsMiddleware\" title=\"django.middleware.common.BrokenLinkEmailsMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.middleware.common.BrokenLinkEmailsMiddleware</span></code></a>。</p></li>\n</ul>\n<p>如以上条件均满足，Django 会在代码抛出 404 错误且请求有对应来源时向 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-MANAGERS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MANAGERS</span></code></a> 配置项中的用户发送邮件。Django 并不会为没有来源的 404s 发送邮件——这些通常是人们或失效的网络爬虫直接输入无效链接。Django 还忽略来源于所请求的 URL 相同的 404s，因为这往往是失效的网络爬虫干的。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p><a class=\"reference internal\" href=\"/zh-hans/2.2/ref/middleware/#django.middleware.common.BrokenLinkEmailsMiddleware\" title=\"django.middleware.common.BrokenLinkEmailsMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BrokenLinkEmailsMiddleware</span></code></a> 必须出现在其它拦截 404 错误的中间层之前，例如 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/middleware/#django.middleware.locale.LocaleMiddleware\" title=\"django.middleware.locale.LocaleMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">LocaleMiddleware</span></code></a> 或 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/contrib/flatpages/#django.contrib.flatpages.middleware.FlatpageFallbackMiddleware\" title=\"django.contrib.flatpages.middleware.FlatpageFallbackMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FlatpageFallbackMiddleware</span></code></a>。将其置于 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a> 配置项的顶部。</p>\n</aside>\n<p>你可以通过调整配置项 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-IGNORABLE_404_URLS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">IGNORABLE_404_URLS</span></code></a> 让 Django 忽略某些 404s。内容应该是已编译的正则表达式的列表。例子:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">re</span>\n<span class=\"n\">IGNORABLE_404_URLS</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;\\.(php|cgi)$&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^/phpmyadmin/&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>在本例中，对以 <code class=\"docutils literal notranslate\"><span class=\"pre\">.php</span></code> 或 <code class=\"docutils literal notranslate\"><span class=\"pre\">.cgi</span></code> 结尾的 URL 的 404 错误将 <em>不会</em> 被报告。以 <code class=\"docutils literal notranslate\"><span class=\"pre\">phpmyadmin</span></code> 开头的也不会被报告。</p>\n<p>下面的例子展示了如何排除一些浏览器和爬虫经常访问的传统 URL:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">re</span>\n<span class=\"n\">IGNORABLE_404_URLS</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^/apple-touch-icon.*\\.png$&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^/favicon\\.ico$&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">compile</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^/robots\\.txt$&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>（注意，这些都是正则表达式，所以我们用反斜杠转义了点号。）</p>\n<p>若后续你想自定义 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/middleware/#django.middleware.common.BrokenLinkEmailsMiddleware\" title=\"django.middleware.common.BrokenLinkEmailsMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.middleware.common.BrokenLinkEmailsMiddleware</span></code></a> 的行为（例如忽略来自网络爬虫的请求），你需要继承该类，并重写方法。</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<p>404 错误由 logging 框架报告。默认情况下，这些日志记录被忽略了，但你能通过编写一个处理器和 <a class=\"reference internal\" href=\"/zh-hans/2.2/topics/logging/\"><span class=\"doc\">配置 logging</span></a> 让它们报告错误。</p>\n</aside>\n</section>\n</section>\n<section id=\"filtering-error-reports\">\n<span id=\"id1\"></span><h2>过滤错误报告<a class=\"heading-anchor\" href=\"#filtering-error-reports\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>过滤敏感数据是个极度困难的问题，且几乎不可能不将敏感数据泄露至错误报告。因此，错误报告应该只对可信任的团队成员开放，并且，你应该避免直接通过明文传输错误报告（例如通过邮件）。</p>\n</aside>\n<section id=\"filtering-sensitive-information\">\n<h3>过滤敏感数据<a class=\"heading-anchor\" href=\"#filtering-sensitive-information\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>错误报告对于调试错误来说超级有用，所以通常尽可能多的记录关键信息。例如，Django 默认记录了抛出异常的 <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Stack_trace\">完整调用栈</a>，每个 <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Stack_frame\">调用栈层</a> 的局部变量，以及 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a> 的 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/request-response/#httprequest-attributes\"><span class=\"std std-ref\">属性</span></a>。</p>\n<p>然而，有时候某些信息会涉及敏感内容，因此不适合写入调用栈。例如，用户的密码或信用卡号。故此，为了过滤 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> 文档中描述的敏感内容，Django 提供了一系列的函数装饰器，帮你控制在生产环境（即 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> 为 <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>）下应该从错误报告中过滤掉哪些信息：<a class=\"reference internal\" href=\"#django.views.decorators.debug.sensitive_variables\" title=\"django.views.decorators.debug.sensitive_variables\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sensitive_variables()</span></code></a> 和 <a class=\"reference internal\" href=\"#django.views.decorators.debug.sensitive_post_parameters\" title=\"django.views.decorators.debug.sensitive_post_parameters\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sensitive_post_parameters()</span></code></a>。</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.views.decorators.debug.sensitive_variables\">\n<span class=\"sig-name descname\"><span class=\"pre\">sensitive_variables</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">variables</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.decorators.debug.sensitive_variables\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>若代码中的一个函数（也可能是视图或定期回调）使用容易包含敏感信息的本地变量，你可以用 <code class=\"docutils literal notranslate\"><span class=\"pre\">sensitive_variables</span></code> 装饰器阻止错误报告包含这些变量的值:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.debug</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sensitive_variables</span>\n\n<span class=\"nd\">@sensitive_variables</span><span class=\"p\">(</span><span class=\"s1\">&#39;user&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pw&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cc&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">process_info</span><span class=\"p\">(</span><span class=\"n\">user</span><span class=\"p\">):</span>\n    <span class=\"n\">pw</span> <span class=\"o\">=</span> <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">pass_word</span>\n    <span class=\"n\">cc</span> <span class=\"o\">=</span> <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">credit_card_number</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">name</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>上述例子中，错误报告中变量 <code class=\"docutils literal notranslate\"><span class=\"pre\">user</span></code>， <code class=\"docutils literal notranslate\"><span class=\"pre\">pw</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">cc</span></code> 的值会被以星开头的字符串(**********)替换 ，不过 <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 变量的值不会被屏蔽。</p>\n<p>要在错误日志中系统的隐藏所有的局部变量，不要向 <code class=\"docutils literal notranslate\"><span class=\"pre\">sensitive_variables</span></code> 装饰器传入任何参数:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@sensitive_variables</span><span class=\"p\">()</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_function</span><span class=\"p\">():</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<aside class=\"admonition-when-using-multiple-decorators admonition\">\n<p class=\"admonition-title\">同时使用多个装饰器时</p>\n<p>若你想隐藏的变量还是一个函数参数（下例中 '<code class=\"docutils literal notranslate\"><span class=\"pre\">user</span></code>’），且被装饰的函数已拥有好几个装饰器，确保将 <code class=\"docutils literal notranslate\"><span class=\"pre\">&#64;sensitive_variables</span></code> 置于最上面。这样，它就也能隐藏函数参数了，因为它穿过其它装饰器:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@sensitive_variables</span><span class=\"p\">(</span><span class=\"s1\">&#39;user&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;pw&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cc&#39;</span><span class=\"p\">)</span>\n<span class=\"nd\">@some_decorator</span>\n<span class=\"nd\">@another_decorator</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">process_info</span><span class=\"p\">(</span><span class=\"n\">user</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</aside>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.views.decorators.debug.sensitive_post_parameters\">\n<span class=\"sig-name descname\"><span class=\"pre\">sensitive_post_parameters</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">*</span></span><span class=\"n\"><span class=\"pre\">parameters</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.decorators.debug.sensitive_post_parameters\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>若视图收到一个包含 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/request-response/#django.http.HttpRequest.POST\" title=\"django.http.HttpRequest.POST\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">POST</span> <span class=\"pre\">参数</span></code></a> 的 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a> 对象，参数中极有可能内含敏感信息。你可以通过 <code class=\"docutils literal notranslate\"><span class=\"pre\">sensitive_post_parameters</span></code> 装饰器避免这些参数的值被包括在错误报告中:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.debug</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sensitive_post_parameters</span>\n\n<span class=\"nd\">@sensitive_post_parameters</span><span class=\"p\">(</span><span class=\"s1\">&#39;pass_word&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;credit_card_number&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">record_user_profile</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">UserProfile</span><span class=\"o\">.</span><span class=\"n\">create</span><span class=\"p\">(</span>\n        <span class=\"n\">user</span><span class=\"o\">=</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"p\">,</span>\n        <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">[</span><span class=\"s1\">&#39;pass_word&#39;</span><span class=\"p\">],</span>\n        <span class=\"n\">credit_card</span><span class=\"o\">=</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">[</span><span class=\"s1\">&#39;credit_card_number&#39;</span><span class=\"p\">],</span>\n        <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">[</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">],</span>\n    <span class=\"p\">)</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>上文例子中，POST 参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">pass_word</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">credit_card_number</span></code> 的值会被隐藏，通过在错误报告中展示请求信息的地方用星号开头的字符串 (**********) 替换，而参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 的值不会被屏蔽。</p>\n<p>要在错误报告中系统的屏蔽所有 POST 参数，不要给 <code class=\"docutils literal notranslate\"><span class=\"pre\">sensitive_post_parameters</span></code> 装饰器提供任何参数:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@sensitive_post_parameters</span><span class=\"p\">()</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>为了避免敏感信息的泄露（例如账号密码）， 所有传入认证视图 <a class=\"reference internal\" href=\"/zh-hans/2.2/topics/auth/default/#module-django.contrib.auth.views\" title=\"django.contrib.auth.views\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.views</span></code></a> （<code class=\"docutils literal notranslate\"><span class=\"pre\">login</span></code>， <code class=\"docutils literal notranslate\"><span class=\"pre\">password_reset_confirm</span></code>， <code class=\"docutils literal notranslate\"><span class=\"pre\">password_change</span></code>， and <code class=\"docutils literal notranslate\"><span class=\"pre\">add_view</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code> 后台中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">user_change_password</span></code>）的 POST 参数都在错误报告中经过系统过滤。</p>\n</dd></dl>\n\n</section>\n<section id=\"custom-error-reports\">\n<span id=\"id2\"></span><h3>自定义错误报告<a class=\"heading-anchor\" href=\"#custom-error-reports\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"#django.views.decorators.debug.sensitive_variables\" title=\"django.views.decorators.debug.sensitive_variables\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sensitive_variables()</span></code></a> 和 <a class=\"reference internal\" href=\"#django.views.decorators.debug.sensitive_post_parameters\" title=\"django.views.decorators.debug.sensitive_post_parameters\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sensitive_post_parameters()</span></code></a> 所做的全部工作是，前者用敏感变量名注解被装饰的函数，后者用 POST 参数中的敏感变量名注解 <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code> 对象，所以敏感信息能在后续错误发生时从报告中过滤出去。这项过滤操作者实际上是由 Django 的默认错误报告处理器： <a class=\"reference internal\" href=\"#django.views.debug.SafeExceptionReporterFilter\" title=\"django.views.debug.SafeExceptionReporterFilter\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.views.debug.SafeExceptionReporterFilter</span></code></a>。该过滤器在错误报告生成时，利用装饰器注解以星号 (**********) 替换指定值。若你想在全站范围重写或自定义该默认行为，你需要定义你的过滤器类，并通过配置项 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEFAULT_EXCEPTION_REPORTER_FILTER\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEFAULT_EXCEPTION_REPORTER_FILTER</span></code></a> 告诉 Django 启用它:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">DEFAULT_EXCEPTION_REPORTER_FILTER</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;path.to.your.CustomExceptionReporterFilter&#39;</span>\n</code></pre></div>\n<p>你也能在任意视图内以一种更细碎的方式控制过滤器，通过设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code> 的 <code class=\"docutils literal notranslate\"><span class=\"pre\">exception_reporter_filter</span></code> 属性:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_authenticated</span><span class=\"p\">:</span>\n        <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">exception_reporter_filter</span> <span class=\"o\">=</span> <span class=\"n\">CustomExceptionReporterFilter</span><span class=\"p\">()</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>自定义过滤器类需要继承自 <a class=\"reference internal\" href=\"#django.views.debug.SafeExceptionReporterFilter\" title=\"django.views.debug.SafeExceptionReporterFilter\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.views.debug.SafeExceptionReporterFilter</span></code></a> 并重写以下方法：</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.views.debug.SafeExceptionReporterFilter\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SafeExceptionReporterFilter</span></span><a class=\"heading-anchor\" href=\"#django.views.debug.SafeExceptionReporterFilter\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.views.debug.SafeExceptionReporterFilter.is_active\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SafeExceptionReporterFilter.</span></span><span class=\"sig-name descname\"><span class=\"pre\">is_active</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">request</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.debug.SafeExceptionReporterFilter.is_active\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>返回 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> 将激活其它方法中的过滤操作。 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> 为 <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> 时，过滤器默认是激活的。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.views.debug.SafeExceptionReporterFilter.get_post_parameters\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SafeExceptionReporterFilter.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_post_parameters</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">request</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.debug.SafeExceptionReporterFilter.get_post_parameters\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>返回 POST 参数过滤后的字典。默认情况下，它将敏感参数的值替换成星号 (**********)。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.views.debug.SafeExceptionReporterFilter.get_traceback_frame_variables\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">SafeExceptionReporterFilter.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_traceback_frame_variables</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">request</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">tb_frame</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.debug.SafeExceptionReporterFilter.get_traceback_frame_variables\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>返回给定的调用栈层中的局部变量经过过滤后的字段。默认情况下，它将敏感参数的值替换成星号 (**********)。</p>\n</dd></dl>\n\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<p>你也能够通过自定义一系列的 <a class=\"reference internal\" href=\"/zh-hans/2.2/topics/http/middleware/#exception-middleware\"><span class=\"std std-ref\">异常中间层</span></a> 定制错误报告行为。若你已经编写了自定义错误处理器，模仿 Django 内置的错误处理器，并只在 <a class=\"reference internal\" href=\"/zh-hans/2.2/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DEBUG</span></code></a> 为 <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> 时报告或记录错误是个不错的主意。</p>\n</aside>\n</section>\n</section>","rootId":"error-reporting","toc":[{"title":"通过邮件方式报告","anchor":"email-reports","children":[{"title":"服务器错误","anchor":"server-errors","children":[]},{"title":"404 错误","anchor":"errors","children":[]}]},{"title":"过滤错误报告","anchor":"filtering-error-reports","children":[{"title":"过滤敏感数据","anchor":"filtering-sensitive-information","children":[]},{"title":"自定义错误报告","anchor":"custom-error-reports","children":[]}]}],"breadcrumbs":[{"docname":"howto/index","title":"操作指南","url":"/zh-hans/2.2/howto/"},{"docname":"howto/deployment/index","title":"部署 Django","url":"/zh-hans/2.2/howto/deployment/"}],"prev":{"docname":"howto/static-files/deployment","title":"部署静态文件","url":"/zh-hans/2.2/howto/static-files/deployment/"},"next":{"docname":"howto/deployment/checklist","title":"部署清单","url":"/zh-hans/2.2/howto/deployment/checklist/"},"formats":{"html":"/zh-hans/2.2/howto/error-reporting/","markdown":"/zh-hans/2.2/howto/error-reporting.md","json":"/zh-hans/2.2/howto/error-reporting.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/howto/error-reporting.txt","official":"https://docs.djangoproject.com/zh-hans/2.2/howto/error-reporting/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}