系統檢查架構
New in Django 1.7.
系統檢查架構是為了驗證Django項目的一系列靜态檢查。它可以檢測到普遍的問題,并且提供如何修複的提示。這個架構可以被擴充,是以你可以輕易地添加你自己的檢查。
檢查可以由
check
指令顯式觸發。檢查會在大多數指令之前隐式觸發,包括
runserver
和
migrate
。由于性能因素,檢查不作為在部署中使用的WSGI棧的一部分運作。如果你需要在你的部署伺服器上運作系統檢查,顯式使用
check
來觸發它們。
嚴重的錯誤會完全阻止Django指令(像
runserver
)的運作。少數問題會通過控制台來報告。如果你檢查了警告的原因,并且願意無視它,你可以使用你項目設定檔案中的
SILENCED_SYSTEM_CHECKS
設定,來隐藏特定的警告。
系統檢查參考中列出了所有Django可執行的所有檢查。
編寫你自己的檢查
這個架構十分靈活,允許你編寫函數,執行任何其他類型的所需檢查。下面是一個樁(stub)檢查函數的例子:
from django.core.checks import register
@register()
def example_check(app_configs, **kwargs):
errors = []
# ... your check logic here
return errors
檢查函數必須接受
app_configs
參數;這個參數是要被檢查的應用清單。如果是None,檢查會運作在項目中所有安裝的應用上。
**kwargs
參數用于進一步的擴充。
消息
這個函數必須傳回消息的清單。如果檢查的結果中沒有發現問題,檢查函數必須傳回一個空清單。
class
CheckMessage
(level, msg, hint, obj=None, id=None)
由檢查方法産生的警告和錯誤必須是
CheckMessage
的示例。
CheckMessage
的執行個體封裝了一個可報告的錯誤或者警告。它同時也提供了可應用到消息的上下文或者提示,以及一個用于過濾的唯一的辨別符。
它的概念非常類似于
消息架構或者
日志架構中的消息。消息使用表明其嚴重性的
level
來标記。
構造器的參數是:
level
The severity of the message. Use one of the
predefined values:
DEBUG
,
INFO
WARNING
ERROR
CRITICAL
. If the level is greater or equal to
ERROR
, then Django
will prevent management commands from executing. Messages with
level lower than
ERROR
(i.e. warnings) are reported to the console,
but can be silenced.
msg
A short (less than 80 characters) string describing the problem. The string
should not contain newlines.
hint
A single-line string providing a hint for fixing the problem. If no hint
can be provided, or the hint is self-evident from the error message, the
hint can be omitted, or a value of
None
can be used.
obj
Optional. An object providing context for the message (for example, the
model where the problem was discovered). The object should be a model, field,
or manager or any other object that defines
__str__
method (on
Python 2 you need to define
__unicode__
method). The method is used while
reporting all messages and its result precedes the message.
id
Optional string. A unique identifier for the issue. Identifiers should
follow the pattern
applabel.X001
, where
X
is one of the letters
CEWID
, indicating the message severity (
C
for criticals,
E
for errors and so). The number can be allocated by the application,
but should be unique within that application.
也有一些快捷方式,使得建立通用級别的消息變得簡單。當使用這些方法時你可以忽略
level
參數,因為它由類名稱暗示。
Debug
(msg, hint, obj=None, id=None)
Info
Warning
Error
Critical
消息是可比較的。你可以輕易地編寫測試:
from django.core.checks import Error
errors = checked_object.check()
expected_errors = [
Error(
'an error',
hint=None,
obj=checked_object,
id='myapp.E001',
)
]
self.assertEqual(errors, expected_errors)
注冊和标記檢查
最後,你的檢查函數必須使用系統檢查登記處來顯式注冊。
register
(*tags)(function)
你可以向
register
傳遞任意數量的标簽來标記你的檢查。Tagging checks is useful since it allows you to run only a certain group of checks. For example, to register a compatibility check, you would make the following call:
from django.core.checks import register, Tags
@register(Tags.compatibility)
def my_check(app_configs, **kwargs):
# ... perform compatibility checks and collect errors
return errors
New in Django 1.8.
你可以注冊“部署的檢查”,它們隻和産品配置檔案相關,像這樣:
@register(Tags.security, deploy=True)
def my_check(app_configs, **kwargs):
...
這些檢查隻在
--deploy
選項傳遞給
check
指令的情況下運作。
你也可以通過向
register
傳遞一個可調用對象(通常是個函數)作為第一個函數,将
register
作為函數使用,而不是一個裝飾器。
下面的代碼和上面等價:
def my_check(app_configs, **kwargs):
...
register(my_check, Tags.security, deploy=True)
Changed in Django 1.8:
添加了将注冊用作函數的功能。
字段、模型和管理器檢查
在一些情況下,你并不需要注冊檢查函數 – 你可以直接使用現有的注冊。
字段、方法和模型管理器都實作了
check()
方法,它已經使用檢查架構注冊。如果你想要添加額外的檢查,你可以擴充基類中的實作,進行任何你需要的額外檢查,并且将任何消息附加到基類生成的消息中。強烈推薦你将每個檢查配置設定到單獨的方法中。
考慮一個例子,其中你要實作一個叫做
RangedIntegerField
的自定義字段。這個字段向
IntegerField
的構造器中添加
min
max
參數。你可能想添加一個檢查,來確定使用者提供了小于等于最大值的最小值。下面的代碼段展示了如何實作這個檢查:
from django.core import checks
from django.db import models
class RangedIntegerField(models.IntegerField):
def __init__(self, min=None, max=None, **kwargs):
super(RangedIntegerField, self).__init__(**kwargs)
self.min = min
self.max = max
def check(self, **kwargs):
# Call the superclass
errors = super(RangedIntegerField, self).check(**kwargs)
# Do some custom checks and add messages to `errors`:
errors.extend(self._check_min_max_values(**kwargs))
# Return all errors and warnings
return errors
def _check_min_max_values(self, **kwargs):
if (self.min is not None and
self.max is not None and
self.min > self.max):
return [
checks.Error(
'min greater than max.',
hint='Decrease min or increase max.',
obj=self,
id='myapp.E001',
)
]
# When no error, return an empty list
return []
如果你想要向模型管理器添加檢查,應該在你的
Manager
的子類上執行同樣的方法。
如果你想要向模型類添加檢查,方法也大緻相同:唯一的不同是檢查是類方法,并不是執行個體方法:
class MyModel(models.Model):
@classmethod
def check(cls, **kwargs):
errors = super(MyModel, cls).check(**kwargs)
# ... your own checks ...
return errors
譯者: Django 文檔協作翻譯小組 ,原文: System check framework。
本文以
CC BY-NC-SA 3.0 協定釋出,轉載請保留作者署名和文章出處。 人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。