New in Django 1.7.
系統(tǒng)檢查框架是為了驗證Django項目的一系列靜態(tài)檢查。它可以檢測到普遍的問題,并且提供如何修復的提示。這個框架可以被擴展,所以你可以輕易地添加你自己的檢查。
檢查可以由check命令顯式觸發(fā)。檢查會在大多數(shù)命令之前隱式觸發(fā),包括runserver 和 migrate。由于性能因素,檢查不作為在部署中使用的WSGI棧的一部分運行。如果你需要在你的部署服務器上運行系統(tǒng)檢查,顯式使用check來觸發(fā)它們。
嚴重的錯誤會完全阻止Django命令(像runserver)的運行。少數(shù)問題會通過控制臺來報告。如果你檢查了警告的原因,并且愿意無視它,你可以使用你項目設(shè)置文件中的SILENCED_SYSTEM_CHECKS 設(shè)置,來隱藏特定的警告。
系統(tǒng)檢查參考中列出了所有Django可執(zhí)行的所有檢查。
這個框架十分靈活,允許你編寫函數(shù),執(zhí)行任何其他類型的所需檢查。下面是一個樁(stub)檢查函數(shù)的例子:
from django.core.checks import register
@register()
def example_check(app_configs, **kwargs):
errors = []
# ... your check logic here
return errors
檢查函數(shù)_必須_接受 app_configs參數(shù);這個參數(shù)是要被檢查的應用列表。如果是None,檢查會運行在項目中_所有_安裝的應用上。**kwargs參數(shù)用于進一步的擴展。
這個函數(shù)必須返回消息的列表。如果檢查的結(jié)果中沒有發(fā)現(xiàn)問題,檢查函數(shù)必須返回一個空列表。
class CheckMessage(level, msg, hint, obj=None, id=None)
由檢查方法產(chǎn)生的警告和錯誤必須是CheckMessage的示例。CheckMessage的實例封裝了一個可報告的錯誤或者警告。它同時也提供了可應用到消息的上下文或者提示,以及一個用于過濾的唯一的標識符。
它的概念非常類似于消息框架或者 日志框架中的消息。消息使用表明其嚴重性的level 來標記。
構(gòu)造器的參數(shù)是:
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.
也有一些快捷方式,使得創(chuàng)建通用級別的消息變得簡單。當使用這些方法時你可以忽略level參數(shù),因為它由類名稱暗示。
class Debug(msg, hint, obj=None, id=None)
class Info(msg, hint, obj=None, id=None)
class Warning(msg, hint, obj=None, id=None)
class Error(msg, hint, obj=None, id=None)
class Critical(msg, hint, obj=None, id=None)
消息是可比較的。你可以輕易地編寫測試:
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)
最后,你的檢查函數(shù)必須使用系統(tǒng)檢查登記處來顯式注冊。
register(*tags)(function)
你可以向 register傳遞任意數(shù)量的標簽來標記你的檢查。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.
你可以注冊“部署的檢查”,它們只和產(chǎn)品配置文件相關(guān),像這樣:
@register(Tags.security, deploy=True)
def my_check(app_configs, **kwargs):
...
這些檢查只在 --deploy 選項傳遞給check 命令的情況下運行。
你也可以通過向register傳遞一個可調(diào)用對象(通常是個函數(shù))作為第一個函數(shù),將 register作為函數(shù)使用,而不是一個裝飾器。
下面的代碼和上面等價:
def my_check(app_configs, **kwargs):
...
register(my_check, Tags.security, deploy=True)
Changed in Django 1.8:
添加了將注冊用作函數(shù)的功能。
在一些情況下,你并不需要注冊檢查函數(shù) -- 你可以直接使用現(xiàn)有的注冊。
字段、方法和模型管理器都實現(xiàn)了check() 方法,它已經(jīng)使用檢查框架注冊。如果你想要添加額外的檢查,你可以擴展基類中的實現(xiàn),進行任何你需要的額外檢查,并且將任何消息附加到基類生成的消息中。強烈推薦你將每個檢查分配到單獨的方法中。
考慮一個例子,其中你要實現(xiàn)一個叫做RangedIntegerField的自定義字段。這個字段向IntegerField的構(gòu)造器中添加min 和 max 參數(shù)。你可能想添加一個檢查,來確保用戶提供了小于等于最大值的最小值。下面的代碼段展示了如何實現(xiàn)這個檢查:
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的子類上執(zhí)行同樣的方法。
如果你想要向模型類添加檢查,方法也_大致_相同:唯一的不同是檢查是類方法,并不是實例方法:
class MyModel(models.Model):
@classmethod
def check(cls, **kwargs):
errors = super(MyModel, cls).check(**kwargs)
# ... your own checks ...
return errors
譯者:Django 文檔協(xié)作翻譯小組,原文:System check framework。
本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請保留作者署名和文章出處。
Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。