{"title":"System check framework","version":"6.1","locale":"el","docname":"topics/checks","url":"/el/6.1/topics/checks/","canonical":"https://djangodocs.dev/el/6.1/topics/checks/","summary":"The system check framework is a set of static checks for validating Django projects. It detects common problems and provides hints for how to fix them. The…","html":"<span id=\"system-check-framework\"></span><h1>System check framework<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>The system check framework is a set of static checks for validating Django\nprojects. It detects common problems and provides hints for how to fix them.\nThe framework is extensible so you can easily add your own checks.</p>\n<p>Checks can be triggered explicitly via the <a class=\"reference internal\" href=\"/el/6.1/ref/django-admin/#django-admin-check\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">check</span></code></a> command. Checks are\ntriggered implicitly before most commands, including <a class=\"reference internal\" href=\"/el/6.1/ref/django-admin/#django-admin-runserver\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">runserver</span></code></a> and\n<a class=\"reference internal\" href=\"/el/6.1/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a>. For performance reasons, checks are not run as part of the\nWSGI stack that is used in deployment. If you need to run system checks on your\ndeployment server, trigger them explicitly using <a class=\"reference internal\" href=\"/el/6.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>Serious errors will prevent Django commands (such as <a class=\"reference internal\" href=\"/el/6.1/ref/django-admin/#django-admin-runserver\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">runserver</span></code></a>) from\nrunning at all. Minor problems are reported to the console. If you have\ninspected the cause of a warning and are happy to ignore it, you can hide\nspecific warnings using the <a class=\"reference internal\" href=\"/el/6.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> setting in your\nproject settings file.</p>\n<p>A full list of all checks that can be raised by Django can be found in the\n<a class=\"reference internal\" href=\"/el/6.1/ref/checks/\"><span class=\"doc\">System check reference</span></a>.</p>\n<section id=\"writing-your-own-checks\">\n<h2>Writing your own checks<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>The framework is flexible and allows you to write functions that perform\nany other kind of check you may require. The following is an example stub\ncheck function:</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>The check function <em>must</em> accept an <code class=\"docutils literal notranslate\"><span class=\"pre\">app_configs</span></code> argument; this argument is\nthe list of applications that should be inspected. If <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, the check must\nbe run on <em>all</em> installed apps in the project.</p>\n<p>The check will receive a <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> keyword argument. This is a list of\ndatabase aliases whose connections may be used to inspect database level\nconfiguration. If <code class=\"docutils literal notranslate\"><span class=\"pre\">databases</span></code> is <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, the check must not use any\ndatabase connections.</p>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code> argument is required for future expansion.</p>\n<section id=\"messages\">\n<h3>Messages<a class=\"heading-anchor\" href=\"#messages\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The function must return a list of messages. If no problems are found as a\nresult of the check, the check function must return an empty list.</p>\n<p>The warnings and errors raised by the check method must be instances of\n<a class=\"reference internal\" href=\"/el/6.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>. An instance of\n<a class=\"reference internal\" href=\"/el/6.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> encapsulates a single reportable\nerror or warning. It also provides context and hints applicable to the\nmessage, and a unique identifier that is used for filtering purposes.</p>\n<p>The concept is very similar to messages from the <a class=\"reference internal\" href=\"/el/6.1/ref/contrib/messages/\"><span class=\"doc\">message framework</span></a> or the <a class=\"reference internal\" href=\"/el/6.1/topics/logging/\"><span class=\"doc\">logging framework</span></a>.\nMessages are tagged with a <code class=\"docutils literal notranslate\"><span class=\"pre\">level</span></code> indicating the severity of the message.</p>\n<p>There are also shortcuts to make creating messages with common levels easier.\nWhen using these classes you can omit the <code class=\"docutils literal notranslate\"><span class=\"pre\">level</span></code> argument because it is\nimplied by the class name.</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/el/6.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=\"/el/6.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=\"/el/6.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=\"/el/6.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=\"/el/6.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>Registering and labeling checks<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>Lastly, your check function must be registered explicitly with system check\nregistry. Checks should be registered in a file that’s loaded when your\napplication is loaded; for example, in the <a class=\"reference internal\" href=\"/el/6.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> method.</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>You can pass as many tags to <code class=\"docutils literal notranslate\"><span class=\"pre\">register</span></code> as you want in order to label your\ncheck. Tagging checks is useful since it allows you to run only a certain\ngroup of checks. For example, to register a compatibility check, you would\nmake the following call:</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>You can register «deployment checks» that are only relevant to a production\nsettings file like this:</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>These checks will only be run if the <a class=\"reference internal\" href=\"/el/6.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> option is used.</p>\n<p>You can also use <code class=\"docutils literal notranslate\"><span class=\"pre\">register</span></code> as a function rather than a decorator by\npassing a callable object (usually a function) as the first argument\nto <code class=\"docutils literal notranslate\"><span class=\"pre\">register</span></code>.</p>\n<p>The code below is equivalent to the code above:</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-constraint-model-manager-template-engine-task-and-database-checks\">\n<span id=\"field-checking\"></span><h3>Field, constraint, model, manager, template engine, task, and database checks<a class=\"heading-anchor\" href=\"#field-constraint-model-manager-template-engine-task-and-database-checks\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>In some cases, you won’t need to register your check function – you can\npiggyback on an existing registration.</p>\n<p>Fields, constraints, models, model managers, template engines, task backends,\nand database backends all implement a <code class=\"docutils literal notranslate\"><span class=\"pre\">check()</span></code> method that is already\nregistered with the check framework. If you want to add extra checks, you can\nextend the implementation on the base class, perform any extra checks you need,\nand append any messages to those generated by the base class. It’s recommended\nthat you delegate each check to separate methods.</p>\n<p>Consider an example where you are implementing a custom field named\n<code class=\"docutils literal notranslate\"><span class=\"pre\">RangedIntegerField</span></code>. This field adds <code class=\"docutils literal notranslate\"><span class=\"pre\">min</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">max</span></code> arguments to the\nconstructor of <code class=\"docutils literal notranslate\"><span class=\"pre\">IntegerField</span></code>. You may want to add a check to ensure that\nusers provide a min value that is less than or equal to the max value. The\nfollowing code snippet shows how you can implement this check:</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>If you wanted to add checks to a model manager, you would take the same\napproach on your subclass of <a class=\"reference internal\" href=\"/el/6.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>If you want to add a check to a model class, the approach is <em>almost</em> the same:\nthe only difference is that the check is a classmethod, not an instance\nmethod:</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=\"6.0\">\n<p class=\"version-note-title\">Changed in Django 6.0</p><p>In older versions, constraints didn’t implement a <code class=\"docutils literal notranslate\"><span class=\"pre\">check()</span></code> method.</p>\n</aside>\n</section>\n<section id=\"writing-tests\">\n<h3>Writing tests<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>Messages are comparable. That allows you to easily write tests:</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>Writing integration tests<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>Given the need to register certain checks when the application loads, it can be\nuseful to test their integration within the system checks framework. This can\nbe accomplished by using the <a class=\"reference internal\" href=\"/el/6.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>\nfunction.</p>\n<p>For example, this test demonstrates that the <a class=\"reference internal\" href=\"/el/6.1/ref/settings/#std-setting-SITE_ID\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SITE_ID</span></code></a> setting must be\nan integer, a built-in <a class=\"reference internal\" href=\"/el/6.1/ref/checks/#sites-system-checks\"><span class=\"std std-ref\">check from the sites framework</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>Consider the following check which issues a warning on deployment if a custom\nsetting named <code class=\"docutils literal notranslate\"><span class=\"pre\">ENABLE_ANALYTICS</span></code> is not set to <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>Given that this check will not raise a <code class=\"docutils literal notranslate\"><span class=\"pre\">SystemCheckError</span></code>, the presence of\nthe warning message in the <code class=\"docutils literal notranslate\"><span class=\"pre\">stderr</span></code> output can be asserted like so:</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":"Writing your own checks","anchor":"writing-your-own-checks","children":[{"title":"Messages","anchor":"messages","children":[]},{"title":"Registering and labeling checks","anchor":"registering-and-labeling-checks","children":[]},{"title":"Field, constraint, model, manager, template engine, task, and database checks","anchor":"field-constraint-model-manager-template-engine-task-and-database-checks","children":[]},{"title":"Writing tests","anchor":"writing-tests","children":[{"title":"Writing integration tests","anchor":"writing-integration-tests","children":[]}]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Using Django","url":"/el/6.1/topics/"}],"prev":{"docname":"topics/signals","title":"Signals","url":"/el/6.1/topics/signals/"},"next":{"docname":"topics/async","title":"Asynchronous support","url":"/el/6.1/topics/async/"},"formats":{"html":"/el/6.1/topics/checks/","markdown":"/el/6.1/topics/checks.md","json":"/el/6.1/topics/checks.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/topics/checks.txt","official":"https://docs.djangoproject.com/el/6.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","1.11","1.10"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}