{"title":"系统检查框架","version":"5.1","locale":"zh-hans","docname":"topics/checks","url":"/zh-hans/5.1/topics/checks/","canonical":"https://djangodocs.dev/zh-hans/5.1/topics/checks/","summary":"系统检查框架是一组验证Django项目的静态检查。 它检测到常见的问题，并提供了如何解决这些问题的提示。 该框架是可扩展的，所以你可以轻松地添加自己的检查。 通过 check 命令来显示的触发检查操作。检查会在大多数命令之前被隐式触发，包括 runserver 和 migrate 。出于性能原因，检查不会作为部署中使用的…","html":"<span id=\"system-check-framework\"></span><h1>系统检查框架<a class=\"heading-anchor\" href=\"#module-django.core.checks\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>系统检查框架是一组验证Django项目的静态检查。 它检测到常见的问题，并提供了如何解决这些问题的提示。 该框架是可扩展的，所以你可以轻松地添加自己的检查。</p>\n<p>通过 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/django-admin/#django-admin-check\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">check</span></code></a> 命令来显示的触发检查操作。检查会在大多数命令之前被隐式触发，包括 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/django-admin/#django-admin-runserver\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">runserver</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a> 。出于性能原因，检查不会作为部署中使用的 WSGI 堆栈的一部分来运行。如果你需要在部署系统上运行系统检查，可以使用 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/django-admin/#django-admin-check\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">check</span></code></a> 来触发他们。</p>\n<p>严重的错误将阻止 Django 命令（比如 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/django-admin/#django-admin-runserver\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">runserver</span></code></a>）运行。小问题将会在控制台上报告出来。如果你已经检查了警告的原因并愿意忽略它，你可以在 settings.py 文件里的 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/settings/#std-setting-SILENCED_SYSTEM_CHECKS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SILENCED_SYSTEM_CHECKS</span></code></a> 设置隐藏指定的警告。</p>\n<p>Django 引发的所有检查的完整列表在 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/\"><span class=\"doc\">System check reference</span></a> 中可查。</p>\n<section id=\"writing-your-own-checks\">\n<h2>编写自定义的检查<a class=\"heading-anchor\" href=\"#writing-your-own-checks\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>框架是可伸缩的，并且允许你编写函数来执行其他你需要的其他检查。举例：</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.core.checks</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Error</span><span class=\"p\">,</span> <span class=\"n\">register</span>\n\n\n<span class=\"nd\">@register</span><span class=\"p\">()</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">example_check</span><span class=\"p\">(</span><span class=\"n\">app_configs</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">errors</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n    <span class=\"c1\"># ... your check logic here</span>\n    <span class=\"k\">if</span> <span class=\"n\">check_failed</span><span class=\"p\">:</span>\n        <span class=\"n\">errors</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span>\n            <span class=\"n\">Error</span><span class=\"p\">(</span>\n                <span class=\"s2\">&quot;an error&quot;</span><span class=\"p\">,</span>\n                <span class=\"n\">hint</span><span class=\"o\">=</span><span class=\"s2\">&quot;A hint.&quot;</span><span class=\"p\">,</span>\n                <span class=\"n\">obj</span><span class=\"o\">=</span><span class=\"n\">checked_object</span><span class=\"p\">,</span>\n                <span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"s2\">&quot;myapp.E001&quot;</span><span class=\"p\">,</span>\n            <span class=\"p\">)</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">errors</span>\n</code></pre></div>\n<p>check 函数必须接受一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">app_configs</span></code> 参数；这个参数是应该被检查的应用程序的列表。如果为 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>，则必须在项目中的 <em>所有</em> 已安装的应用程序上运行检查。</p>\n<p>检查将接收一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> 关键字参数。这是一个数据库别名的列表，其连接可能用于检查数据库级别的配置。如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> 为 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>，则检查必须不使用任何数据库连接。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code> 参数是为了将来扩展而必需的。</p>\n<section id=\"messages\">\n<h3>消息<a class=\"heading-anchor\" href=\"#messages\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>函数必须返回消息列表。如果检查结果没有发现问题，检查函数必须返回空列表。</p>\n<p>警告和错误由必须是 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#django.core.checks.CheckMessage\" title=\"django.core.checks.CheckMessage\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CheckMessage</span></code></a> 的检查方法引发。<a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#django.core.checks.CheckMessage\" title=\"django.core.checks.CheckMessage\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CheckMessage</span></code></a> 的实例概括了错误或警告。它也提供适合消息的上下文和消息，和用来过滤目的的唯一标示。</p>\n<p>这个概念与来自  <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/contrib/messages/\"><span class=\"doc\">message framework</span></a> or the <a class=\"reference internal\" href=\"/zh-hans/5.1/topics/logging/\"><span class=\"doc\">logging framework</span></a> 的消息非常相似。消息标有 <code class=\"docutils literal notranslate\"><span class=\"pre\">level</span></code> ，标示消息的严重性。</p>\n<p>也可以有快捷方式来简单创建公共级别的消息。当使用这些类你可以忽略 <code class=\"docutils literal notranslate\"><span class=\"pre\">level</span></code> 参数，因为它已经通过类名隐含。</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#django.core.checks.Debug\" title=\"django.core.checks.Debug\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Debug</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#django.core.checks.Info\" title=\"django.core.checks.Info\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Info</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#django.core.checks.Warning\" title=\"django.core.checks.Warning\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Warning</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#django.core.checks.Error\" title=\"django.core.checks.Error\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Error</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#django.core.checks.Critical\" title=\"django.core.checks.Critical\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Critical</span></code></a></p></li>\n</ul>\n</section>\n<section id=\"registering-and-labeling-checks\">\n<span id=\"registering-labeling-checks\"></span><h3>注册和标记检查<a class=\"heading-anchor\" href=\"#registering-and-labeling-checks\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>最后，你的检查函数必须已经在系统检查注册表明确注册。检查应该在加载应用程序时加载文件中注册；比如，在 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">AppConfig.ready()</span></code></a> 方法中。</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.core.checks.register\">\n<span class=\"sig-name descname\"><span class=\"pre\">register</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">*tags)(function</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.checks.register\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>为了标记检查，你可以根据需要来传递很多标签给 <code class=\"docutils literal notranslate\"><span class=\"pre\">register</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.core.checks</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">register</span><span class=\"p\">,</span> <span class=\"n\">Tags</span>\n\n\n<span class=\"nd\">@register</span><span class=\"p\">(</span><span class=\"n\">Tags</span><span class=\"o\">.</span><span class=\"n\">compatibility</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_check</span><span class=\"p\">(</span><span class=\"n\">app_configs</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ... perform compatibility checks and collect errors</span>\n    <span class=\"k\">return</span> <span class=\"n\">errors</span>\n</code></pre></div>\n<p>你可以注册仅与生产配置文件相关的&quot;部署检查&quot; ：</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\">@register</span><span class=\"p\">(</span><span class=\"n\">Tags</span><span class=\"o\">.</span><span class=\"n\">security</span><span class=\"p\">,</span> <span class=\"n\">deploy</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_check</span><span class=\"p\">(</span><span class=\"n\">app_configs</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>这些检查只在使用 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/django-admin/#cmdoption-check-deploy\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">check</span> <span class=\"pre\">--deploy</span></code></a> 选项时运行。</p>\n<p>你也可以把 <code class=\"docutils literal notranslate\"><span class=\"pre\">register</span></code> 当做函数而不是装饰器，通过传递一个可调用对象（通常是函数）作为第一参数传递给 <code class=\"docutils literal notranslate\"><span class=\"pre\">register</span></code>。</p>\n<p>下面的代码和上面的代码等同：</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_check</span><span class=\"p\">(</span><span class=\"n\">app_configs</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n\n\n<span class=\"n\">register</span><span class=\"p\">(</span><span class=\"n\">my_check</span><span class=\"p\">,</span> <span class=\"n\">Tags</span><span class=\"o\">.</span><span class=\"n\">security</span><span class=\"p\">,</span> <span class=\"n\">deploy</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"field-model-manager-template-engine-and-database-checks\">\n<span id=\"field-checking\"></span><h3>字段、模型、管理器、模板引擎和数据库检查<a class=\"heading-anchor\" href=\"#field-model-manager-template-engine-and-database-checks\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>在某些情况下，你不需要注册检查函数——你可以使用现有的注册。</p>\n<p>字段、模型、模型管理器、模板引擎和数据库后端都实现了一个已经注册到检查框架中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">check()</span></code> 方法。如果你想添加额外的检查，可以在基类上扩展实现，执行你需要的任何额外检查，并将任何消息附加到基类生成的消息中。建议你将每个检查委托给单独的方法。</p>\n<p>考虑一个例子，你正在实现一个自定义字段 <code class=\"docutils literal notranslate\"><span class=\"pre\">RangedIntegerField</span></code>。这个字段添加 <code class=\"docutils literal notranslate\"><span class=\"pre\">min</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">max</span></code> 参数给 <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerField</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.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">checks</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">RangedIntegerField</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">IntegerField</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"nb\">min</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"nb\">max</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">min</span> <span class=\"o\">=</span> <span class=\"nb\">min</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">max</span> <span class=\"o\">=</span> <span class=\"nb\">max</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">check</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Call the superclass</span>\n        <span class=\"n\">errors</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">check</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Do some custom checks and add messages to `errors`:</span>\n        <span class=\"n\">errors</span><span class=\"o\">.</span><span class=\"n\">extend</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_min_max_values</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">))</span>\n\n        <span class=\"c1\"># Return all errors and warnings</span>\n        <span class=\"k\">return</span> <span class=\"n\">errors</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">_check_min_max_values</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">min</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">max</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">min</span> <span class=\"o\">&gt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"p\">[</span>\n                <span class=\"n\">checks</span><span class=\"o\">.</span><span class=\"n\">Error</span><span class=\"p\">(</span>\n                    <span class=\"s2\">&quot;min greater than max.&quot;</span><span class=\"p\">,</span>\n                    <span class=\"n\">hint</span><span class=\"o\">=</span><span class=\"s2\">&quot;Decrease min or increase max.&quot;</span><span class=\"p\">,</span>\n                    <span class=\"n\">obj</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"p\">,</span>\n                    <span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"s2\">&quot;myapp.E001&quot;</span><span class=\"p\">,</span>\n                <span class=\"p\">)</span>\n            <span class=\"p\">]</span>\n        <span class=\"c1\"># When no error, return an empty list</span>\n        <span class=\"k\">return</span> <span class=\"p\">[]</span>\n</code></pre></div>\n<p>如果你想对模型管理器添加检查，你应该对 <a class=\"reference internal\" href=\"/zh-hans/5.1/topics/db/managers/#django.db.models.Manager\" title=\"django.db.models.Manager\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Manager</span></code></a> 的子类采用相同方法。</p>\n<p>如果你想对模型类添加检查，这个方法几乎相同，唯一的区别是这个检查是一个类方法，而不是实例方法。</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\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">check</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"n\">errors</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">check</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n        <span class=\"c1\"># ... your own checks ...</span>\n        <span class=\"k\">return</span> <span class=\"n\">errors</span>\n</code></pre></div>\n<aside class=\"version-note version-changed\" data-version=\"5.1\">\n<p class=\"version-note-title\">Changed in Django 5.1</p><p>在旧版本中，模板引擎没有实现 <code class=\"docutils literal notranslate\"><span class=\"pre\">check()</span></code> 方法。</p>\n</aside>\n</section>\n<section id=\"writing-tests\">\n<h3>编写测试<a class=\"heading-anchor\" href=\"#writing-tests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>消息具有可比性。允许你轻松编写测试：</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.core.checks</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Error</span>\n\n<span class=\"n\">errors</span> <span class=\"o\">=</span> <span class=\"n\">checked_object</span><span class=\"o\">.</span><span class=\"n\">check</span><span class=\"p\">()</span>\n<span class=\"n\">expected_errors</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">Error</span><span class=\"p\">(</span>\n        <span class=\"s2\">&quot;an error&quot;</span><span class=\"p\">,</span>\n        <span class=\"n\">hint</span><span class=\"o\">=</span><span class=\"s2\">&quot;A hint.&quot;</span><span class=\"p\">,</span>\n        <span class=\"n\">obj</span><span class=\"o\">=</span><span class=\"n\">checked_object</span><span class=\"p\">,</span>\n        <span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"s2\">&quot;myapp.E001&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">)</span>\n<span class=\"p\">]</span>\n<span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">errors</span><span class=\"p\">,</span> <span class=\"n\">expected_errors</span><span class=\"p\">)</span>\n</code></pre></div>\n<section id=\"writing-integration-tests\">\n<h4>编写集成测试<a class=\"heading-anchor\" href=\"#writing-integration-tests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>由于在应用程序加载时需要注册某些检查，因此测试它们在系统检查框架内的集成可以是有用的。这可以通过使用 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/django-admin/#django.core.management.call_command\" title=\"django.core.management.call_command\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">call_command()</span></code></a> 函数来实现。</p>\n<p>例如，这个测试演示了:setting:SITE_ID 设置必须是一个整数，这是来自站点框架的内置 <a class=\"reference internal\" href=\"/zh-hans/5.1/ref/checks/#sites-system-checks\"><span class=\"std std-ref\">检查</span></a>:</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.core.management</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">call_command</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.management.base</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SystemCheckError</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SimpleTestCase</span><span class=\"p\">,</span> <span class=\"n\">modify_settings</span><span class=\"p\">,</span> <span class=\"n\">override_settings</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SystemCheckIntegrationTest</span><span class=\"p\">(</span><span class=\"n\">SimpleTestCase</span><span class=\"p\">):</span>\n    <span class=\"nd\">@override_settings</span><span class=\"p\">(</span><span class=\"n\">SITE_ID</span><span class=\"o\">=</span><span class=\"s2\">&quot;non_integer&quot;</span><span class=\"p\">)</span>\n    <span class=\"nd\">@modify_settings</span><span class=\"p\">(</span><span class=\"n\">INSTALLED_APPS</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;prepend&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.contrib.sites&quot;</span><span class=\"p\">})</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_non_integer_site_id</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">message</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;(sites.E101) The SITE_ID setting must be an integer.&quot;</span>\n        <span class=\"k\">with</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertRaisesMessage</span><span class=\"p\">(</span><span class=\"n\">SystemCheckError</span><span class=\"p\">,</span> <span class=\"n\">message</span><span class=\"p\">):</span>\n            <span class=\"n\">call_command</span><span class=\"p\">(</span><span class=\"s2\">&quot;check&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>考虑以下检查，如果自定义设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">ENABLE_ANALYTICS</span></code> 未设置为 <code class=\"docutils literal notranslate\"><span class=\"pre\">True</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.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.checks</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"ne\">Warning</span><span class=\"p\">,</span> <span class=\"n\">register</span>\n\n\n<span class=\"nd\">@register</span><span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"n\">deploy</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">check_enable_analytics_is_true_on_deploy</span><span class=\"p\">(</span><span class=\"n\">app_configs</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">errors</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n    <span class=\"k\">if</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"n\">settings</span><span class=\"p\">,</span> <span class=\"s2\">&quot;ENABLE_ANALYTICS&quot;</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">True</span><span class=\"p\">:</span>\n        <span class=\"n\">errors</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span>\n            <span class=\"ne\">Warning</span><span class=\"p\">(</span>\n                <span class=\"s2\">&quot;The ENABLE_ANALYTICS setting should be set to True in deployment.&quot;</span><span class=\"p\">,</span>\n                <span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"s2\">&quot;myapp.W001&quot;</span><span class=\"p\">,</span>\n            <span class=\"p\">)</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">errors</span>\n</code></pre></div>\n<p>鉴于这个检查不会引发 <code class=\"docutils literal notranslate\"><span class=\"pre\">SystemCheckError</span></code>，可以通过以下方式断言 <code class=\"docutils literal notranslate\"><span class=\"pre\">stderr</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\">io</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">StringIO</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.management</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">call_command</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SimpleTestCase</span><span class=\"p\">,</span> <span class=\"n\">override_settings</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">EnableAnalyticsDeploymentCheckTest</span><span class=\"p\">(</span><span class=\"n\">SimpleTestCase</span><span class=\"p\">):</span>\n    <span class=\"nd\">@override_settings</span><span class=\"p\">(</span><span class=\"n\">ENABLE_ANALYTICS</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_when_set_to_none</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">stderr</span> <span class=\"o\">=</span> <span class=\"n\">StringIO</span><span class=\"p\">()</span>\n        <span class=\"n\">call_command</span><span class=\"p\">(</span><span class=\"s2\">&quot;check&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;-t&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;--deploy&quot;</span><span class=\"p\">,</span> <span class=\"n\">stderr</span><span class=\"o\">=</span><span class=\"n\">stderr</span><span class=\"p\">)</span>\n        <span class=\"n\">message</span> <span class=\"o\">=</span> <span class=\"p\">(</span>\n            <span class=\"s2\">&quot;(myapp.W001) The ENABLE_ANALYTICS setting should be set &quot;</span>\n            <span class=\"s2\">&quot;to True in deployment.&quot;</span>\n        <span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertIn</span><span class=\"p\">(</span><span class=\"n\">message</span><span class=\"p\">,</span> <span class=\"n\">stderr</span><span class=\"o\">.</span><span class=\"n\">getvalue</span><span class=\"p\">())</span>\n</code></pre></div>\n</section>\n</section>\n</section>","rootId":"module-django.core.checks","toc":[{"title":"编写自定义的检查","anchor":"writing-your-own-checks","children":[{"title":"消息","anchor":"messages","children":[]},{"title":"注册和标记检查","anchor":"registering-and-labeling-checks","children":[]},{"title":"字段、模型、管理器、模板引擎和数据库检查","anchor":"field-model-manager-template-engine-and-database-checks","children":[]},{"title":"编写测试","anchor":"writing-tests","children":[{"title":"编写集成测试","anchor":"writing-integration-tests","children":[]}]}]}],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/5.1/topics/"}],"prev":{"docname":"topics/signals","title":"信号","url":"/zh-hans/5.1/topics/signals/"},"next":{"docname":"topics/external-packages","title":"扩展包","url":"/zh-hans/5.1/topics/external-packages/"},"formats":{"html":"/zh-hans/5.1/topics/checks/","markdown":"/zh-hans/5.1/topics/checks.md","json":"/zh-hans/5.1/topics/checks.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/topics/checks.txt","official":"https://docs.djangoproject.com/zh-hans/5.1/topics/checks/","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","it","pt-br","ko","es","el","pl"]}