checks.txt 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. ======================
  2. System check framework
  3. ======================
  4. .. versionadded:: 1.7
  5. .. module:: django.core.checks
  6. The system check framework is a set of static checks for validating Django
  7. projects. It detects common problems and provides hints for how to fix them.
  8. The framework is extensible so you can easily add your own checks.
  9. Checks can be triggered explicitly via the :djadmin:`check` command. Checks are
  10. triggered implicitly before most commands, including :djadmin:`runserver` and
  11. :djadmin:`migrate`. For performance reasons, the checks are not performed if
  12. :setting:`DEBUG` is set to ``False``.
  13. Serious errors will prevent Django commands (such as :djadmin:`runserver`) from
  14. running at all. Minor problems are reported to the console. If you have inspected
  15. the cause of a warning and are happy to ignore it, you can hide specific warnings
  16. using the :setting:`SILENCED_SYSTEM_CHECKS` setting in your project settings file.
  17. Writing your own checks
  18. =======================
  19. The framework is flexible and allows you to write functions that perform
  20. any other kind of check you may require. The following is an example stub
  21. check function::
  22. from django.core.checks import register
  23. @register()
  24. def example_check(app_configs, **kwargs):
  25. errors = []
  26. # ... your check logic here
  27. return errors
  28. The check function *must* accept an ``app_configs`` argument; this argument is
  29. the list of applications that should be inspected. If None, the check must be
  30. run on *all* installed apps in the project. The ``**kwargs`` argument is required
  31. for future expansion.
  32. Messages
  33. --------
  34. The function must return a list of messages. If no problems are found as a result
  35. of the check, the check function must return an empty list.
  36. .. class:: CheckMessage(level, msg, hint, obj=None, id=None)
  37. The warnings and errors raised by the check method must be instances of
  38. :class:`~django.core.checks.CheckMessage`. An instance of
  39. :class:`~django.core.checks.CheckMessage` encapsulates a single reportable
  40. error or warning. It also provides context and hints applicable to the
  41. message, and a unique identifier that is used for filtering purposes.
  42. The concept is very similar to messages from the :doc:`message
  43. framework </ref/contrib/messages>` or the :doc:`logging framework
  44. </topics/logging>`. Messages are tagged with a ``level`` indicating the
  45. severity of the message.
  46. Constructor arguments are:
  47. ``level``
  48. The severity of the message. Use one of the
  49. predefined values: ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``,
  50. ``CRITICAL``. If the level is greater or equal to ``ERROR``, then Django
  51. will prevent management commands from executing. Messages with
  52. level lower than ``ERROR`` (i.e. warnings) are reported to the console,
  53. but can be silenced.
  54. ``msg``
  55. A short (less than 80 characters) string describing the problem. The string
  56. should *not* contain newlines.
  57. ``hint``
  58. A single-line string providing a hint for fixing the problem. If no hint
  59. can be provided, or the hint is self-evident from the error message, a
  60. value of ``None`` can be used::
  61. Error('error message') # Will not work.
  62. Error('error message', None) # Good
  63. Error('error message', hint=None) # Better
  64. ``obj``
  65. Optional. An object providing context for the message (for example, the
  66. model where the problem was discovered). The object should be a model, field,
  67. or manager or any other object that defines ``__str__`` method (on
  68. Python 2 you need to define ``__unicode__`` method). The method is used while
  69. reporting all messages and its result precedes the message.
  70. ``id``
  71. Optional string. A unique identifier for the issue. Identifiers should
  72. follow the pattern ``applabel.X001``, where ``X`` is one of the letters
  73. ``CEWID``, indicating the message severity (``C`` for criticals,
  74. ``E`` for errors and so). The number can be allocated by the application,
  75. but should be unique within that application.
  76. There are also shortcuts to make creating messages with common levels easier.
  77. When using these methods you can omit the ``level`` argument because it is
  78. implied by the class name.
  79. .. class:: Debug(msg, hint, obj=None, id=None)
  80. .. class:: Info(msg, hint, obj=None, id=None)
  81. .. class:: Warning(msg, hint, obj=None, id=None)
  82. .. class:: Error(msg, hint, obj=None, id=None)
  83. .. class:: Critical(msg, hint, obj=None, id=None)
  84. Messages are comparable. That allows you to easily write tests::
  85. from django.core.checks import Error
  86. errors = checked_object.check()
  87. expected_errors = [
  88. Error(
  89. 'an error',
  90. hint=None,
  91. obj=checked_object,
  92. id='myapp.E001',
  93. )
  94. ]
  95. self.assertEqual(errors, expected_errors)
  96. Registering and labeling checks
  97. -------------------------------
  98. Lastly, your check function must be registered explicitly with system check
  99. registry.
  100. .. function:: register(*tags)(function)
  101. You can pass as many tags to ``register`` as you want in order to label your
  102. check. Tagging checks is useful since it allows you to run only a certain
  103. group of checks. For example, to register a compatibility check, you would
  104. make the following call::
  105. from django.core.checks import register
  106. @register('compatibility')
  107. def my_check(app_configs, **kwargs):
  108. # ... perform compatibility checks and collect errors
  109. return errors
  110. .. _field-checking:
  111. Field, Model, and Manager checks
  112. --------------------------------
  113. In some cases, you won't need to register your check function -- you can
  114. piggyback on an existing registration.
  115. Fields, models, and model managers all implement a ``check()`` method that is
  116. already registered with the check framework. If you want to add extra checks,
  117. you can extend the implementation on the base class, perform any extra
  118. checks you need, and append any messages to those generated by the base class.
  119. It's recommended the you delegate each check to a separate methods.
  120. Consider an example where you are implementing a custom field named
  121. ``RangedIntegerField``. This field adds ``min`` and ``max`` arguments to the
  122. constructor of ``IntegerField``. You may want to add a check to ensure that users
  123. provide a min value that is less than or equal to the max value. The following
  124. code snippet shows how you can implement this check::
  125. from django.core import checks
  126. from django.db import models
  127. class RangedIntegerField(models.IntegerField):
  128. def __init__(self, min=None, max=None, **kwargs):
  129. super(RangedIntegerField, self).__init__(**kwargs)
  130. self.min = min
  131. self.max = max
  132. def check(self, **kwargs):
  133. # Call the superclass
  134. errors = super(RangedIntegerField, self).check(**kwargs)
  135. # Do some custom checks and add messages to `errors`:
  136. errors.extend(self._check_min_max_values(**kwargs))
  137. # Return all errors and warnings
  138. return errors
  139. def _check_min_max_values(self, **kwargs):
  140. if (self.min is not None and
  141. self.max is not None and
  142. self.min > self.max):
  143. return [
  144. checks.Error(
  145. 'min greated than max.',
  146. hint='Decrease min or increase max.',
  147. obj=self,
  148. id='myapp.E001',
  149. )
  150. ]
  151. # When no error, return an empty list
  152. return []
  153. If you wanted to add checks to a model manager, you would take the same
  154. approach on your subclass of :class:`~django.db.models.Manager`.
  155. If you want to add a check to a model class, the approach is *almost* the same:
  156. the only difference is that the check is a classmethod, not an instance method::
  157. class MyModel(models.Model):
  158. @classmethod
  159. def check(cls, **kwargs):
  160. errors = super(MyModel, cls).check(**kwargs)
  161. # ... your own checks ...
  162. return errors