鍍金池/ 教程/ Python/ 系統(tǒng)檢查框架
點(diǎn)擊劫持保護(hù)
安全問(wèn)題歸檔
Model 類參考
將遺留數(shù)據(jù)庫(kù)整合到Django
關(guān)聯(lián)對(duì)象參考
內(nèi)建基于類的視圖的API
聚合
Django 中的用戶認(rèn)證
django.contrib.humanize
Django管理文檔生成器
分頁(yè)
使用Django輸出CSV
加密簽名
文件儲(chǔ)存API
安全
Django中的測(cè)試
國(guó)際化和本地化
為Django編寫首個(gè)補(bǔ)丁
條件表達(dá)式
日志
模型元選項(xiàng)
部署靜態(tài)文件
執(zhí)行查詢
使用Django認(rèn)證系統(tǒng)
基于類的視圖
中間件
編寫自定義的django-admin命令
Django 的設(shè)置
格式本地化
數(shù)據(jù)庫(kù)訪問(wèn)優(yōu)化
錯(cuò)誤報(bào)告
基于類的內(nèi)建通用視圖
編寫自定義存儲(chǔ)系統(tǒng)
編寫你的第一個(gè) Django 程序 第3部分
編寫數(shù)據(jù)庫(kù)遷移
使用表單
編寫你的第一個(gè) Django 程序 第2部分
編寫你的第一個(gè) Django 程序 第1部分
如何使用會(huì)話
系統(tǒng)檢查框架
新手入門
信號(hào)
編寫視圖
如何使用WSGI 部署
編寫你的第一個(gè)Django應(yīng)用,第6部分
常見的網(wǎng)站應(yīng)用工具
Widgets
內(nèi)建的視圖
模型實(shí)例參考
視圖層
Django中的密碼管理
高級(jí)教程:如何編寫可重用的應(yīng)用
國(guó)際化和本地化
"本地特色"附加功能
TemplateResponse 和 SimpleTemplateResponse
模式編輯器
文件上傳
快速安裝指南
部署 Django
表單 API
表單素材 ( <code>Media</code> 類)
管理文件
其它核心功能
查找 API 參考
表單
Admin
數(shù)據(jù)庫(kù)函數(shù)
自定義查找
使用基于類的視圖處理表單
管理操作
開發(fā)過(guò)程
編寫你的第一個(gè)Django應(yīng)用,第5部分
進(jìn)行原始的sql查詢
模型層
多數(shù)據(jù)庫(kù)
編寫你的第一個(gè) Django 程序 第4部分
Django安全
Django 初探
Django異常
重定向應(yīng)用
按需內(nèi)容處理
管理器
視圖裝飾器
驗(yàn)證器
使用Django輸出PDF
File對(duì)象
Django 的快捷函數(shù)
基于類的通用視圖 —— 索引
為模型提供初始數(shù)據(jù)
模板層
URL調(diào)度器
中間件
模型

系統(tǒng)檢查框架

New in Django 1.7.

系統(tǒng)檢查框架是為了驗(yàn)證Django項(xiàng)目的一系列靜態(tài)檢查。它可以檢測(cè)到普遍的問(wèn)題,并且提供如何修復(fù)的提示。這個(gè)框架可以被擴(kuò)展,所以你可以輕易地添加你自己的檢查。

檢查可以由check命令顯式觸發(fā)。檢查會(huì)在大多數(shù)命令之前隱式觸發(fā),包括runservermigrate。由于性能因素,檢查不作為在部署中使用的WSGI棧的一部分運(yùn)行。如果你需要在你的部署服務(wù)器上運(yùn)行系統(tǒng)檢查,顯式使用check來(lái)觸發(fā)它們。

嚴(yán)重的錯(cuò)誤會(huì)完全阻止Django命令(像runserver)的運(yùn)行。少數(shù)問(wèn)題會(huì)通過(guò)控制臺(tái)來(lái)報(bào)告。如果你檢查了警告的原因,并且愿意無(wú)視它,你可以使用你項(xiàng)目設(shè)置文件中的SILENCED_SYSTEM_CHECKS 設(shè)置,來(lái)隱藏特定的警告。

系統(tǒng)檢查參考中列出了所有Django可執(zhí)行的所有檢查。

編寫你自己的檢查

這個(gè)框架十分靈活,允許你編寫函數(shù),執(zhí)行任何其他類型的所需檢查。下面是一個(gè)樁(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ù);這個(gè)參數(shù)是要被檢查的應(yīng)用列表。如果是None,檢查會(huì)運(yùn)行在項(xiàng)目中_所有_安裝的應(yīng)用上。**kwargs參數(shù)用于進(jìn)一步的擴(kuò)展。

消息

這個(gè)函數(shù)必須返回消息的列表。如果檢查的結(jié)果中沒有發(fā)現(xiàn)問(wèn)題,檢查函數(shù)必須返回一個(gè)空列表。

class CheckMessage(level, msg, hint, obj=None, id=None)

由檢查方法產(chǎn)生的警告和錯(cuò)誤必須是CheckMessage的示例。CheckMessage的實(shí)例封裝了一個(gè)可報(bào)告的錯(cuò)誤或者警告。它同時(shí)也提供了可應(yīng)用到消息的上下文或者提示,以及一個(gè)用于過(guò)濾的唯一的標(biāo)識(shí)符。

它的概念非常類似于消息框架或者 日志框架中的消息。消息使用表明其嚴(yán)重性的level 來(lái)標(biāo)記。

構(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)建通用級(jí)別的消息變得簡(jiǎn)單。當(dāng)使用這些方法時(shí)你可以忽略level參數(shù),因?yàn)樗深惷Q暗示。

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)

消息是可比較的。你可以輕易地編寫測(cè)試:

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)

注冊(cè)和標(biāo)記檢查

最后,你的檢查函數(shù)必須使用系統(tǒng)檢查登記處來(lái)顯式注冊(cè)。

register(*tags)(function)

你可以向 register傳遞任意數(shù)量的標(biāo)簽來(lái)標(biāo)記你的檢查。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.

你可以注冊(cè)“部署的檢查”,它們只和產(chǎn)品配置文件相關(guān),像這樣:

@register(Tags.security, deploy=True)
def my_check(app_configs, **kwargs):
    ...

這些檢查只在 --deploy 選項(xiàng)傳遞給check 命令的情況下運(yùn)行。

你也可以通過(guò)向register傳遞一個(gè)可調(diào)用對(duì)象(通常是個(gè)函數(shù))作為第一個(gè)函數(shù),將 register作為函數(shù)使用,而不是一個(gè)裝飾器。

下面的代碼和上面等價(jià):

def my_check(app_configs, **kwargs):
    ...
register(my_check, Tags.security, deploy=True)

Changed in Django 1.8:

添加了將注冊(cè)用作函數(shù)的功能。

字段、模型和管理器檢查

在一些情況下,你并不需要注冊(cè)檢查函數(shù) -- 你可以直接使用現(xiàn)有的注冊(cè)。

字段、方法和模型管理器都實(shí)現(xiàn)了check() 方法,它已經(jīng)使用檢查框架注冊(cè)。如果你想要添加額外的檢查,你可以擴(kuò)展基類中的實(shí)現(xiàn),進(jìn)行任何你需要的額外檢查,并且將任何消息附加到基類生成的消息中。強(qiáng)烈推薦你將每個(gè)檢查分配到單獨(dú)的方法中。

考慮一個(gè)例子,其中你要實(shí)現(xiàn)一個(gè)叫做RangedIntegerField的自定義字段。這個(gè)字段向IntegerField的構(gòu)造器中添加minmax 參數(shù)。你可能想添加一個(gè)檢查,來(lái)確保用戶提供了小于等于最大值的最小值。下面的代碼段展示了如何實(shí)現(xiàn)這個(gè)檢查:

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 []

如果你想要向模型管理器添加檢查,應(yīng)該在你的Manager的子類上執(zhí)行同樣的方法。

如果你想要向模型類添加檢查,方法也_大致_相同:唯一的不同是檢查是類方法,并不是實(shí)例方法:

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)載請(qǐng)保留作者署名和文章出處。

Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。