天天看點

django 1.8 官方文檔翻譯:14-6 系統檢查架構系統檢查架構

系統檢查架構

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。