システムチェックフレームワーク—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/topics/checks
移動先:案内検索

システムチェックフレームワーク

システムチェックフレームワークは、Djangoプロジェクトを検証するための一連の静的チェックです。 一般的な問題を検出し、それらを修正する方法のヒントを提供します。 フレームワークは拡張可能であるため、独自のチェックを簡単に追加できます。

チェックは、:djadmin: `check` コマンドを使用して明示的にトリガーできます。 チェックは、:djadmin: `runserver`:djadmin:` migrate` を含むほとんどのコマンドの前に暗黙的にトリガーされます。 パフォーマンス上の理由から、展開で使用されるWSGIスタックの一部としてチェックは実行されません。 デプロイメントサーバーでシステムチェックを実行する必要がある場合は、:djadmin: `check` を使用して明示的にトリガーします。

重大なエラーが発生すると、Djangoコマンド(:djadmin: `runserver` など)がまったく実行されなくなります。 軽微な問題はコンソールに報告されます。 警告の原因を調べて無視してもかまわない場合は、プロジェクト設定ファイルの:setting: `SILENCED_SYSTEM_CHECKS` 設定を使用して、特定の警告を非表示にすることができます。

Djangoで発生する可能性のあるすべてのチェックの完全なリストは、システムチェックリファレンスにあります。

独自の小切手を書く

フレームワークは柔軟性があり、必要な他の種類のチェックを実行する関数を記述できます。 以下は、スタブチェック関数の例です。

from django.core.checks import Error, register

@register()
def example_check(app_configs, **kwargs):
    errors = []
    # ... your check logic here
    if check_failed:
        errors.append(
            Error(
                'an error',
                hint='A hint.',
                obj=checked_object,
                id='myapp.E001',
            )
        )
    return errors

チェック関数app_configs引数を受け入れる必要があります。 この引数は、検査する必要のあるアプリケーションのリストです。 Noneの場合、プロジェクトにインストールされているすべてのアプリでチェックを実行する必要があります。

小切手はdatabasesキーワード引数を受け取ります。 これは、データベースレベルの構成を検査するために接続を使用できるデータベースエイリアスのリストです。 databasesNoneの場合、チェックでデータベース接続を使用しないでください。

**kwargs引数は、将来の拡張に必要です。

メッセージ

関数はメッセージのリストを返す必要があります。 チェックの結果、問題が見つからなかった場合、チェック関数は空のリストを返す必要があります。

checkメソッドによって発生する警告とエラーは、 CheckMessage のインスタンスである必要があります。 CheckMessage のインスタンスは、単一の報告可能なエラーまたは警告をカプセル化します。 また、メッセージに適用可能なコンテキストとヒント、およびフィルタリングの目的で使用される一意の識別子も提供します。

概念は、メッセージフレームワークまたはロギングフレームワークからのメッセージと非常によく似ています。 メッセージには、メッセージの重大度を示すlevelのタグが付けられます。

共通レベルのメッセージを簡単に作成するためのショートカットもあります。 これらのクラスを使用する場合、level引数はクラス名によって暗示されるため、省略できます。


小切手の登録とラベル付け

最後に、チェック機能をシステムチェックレジストリに明示的に登録する必要があります。 小切手は、アプリケーションのロード時にロードされるファイルに登録する必要があります。 たとえば、 AppConfig.ready()メソッド。

register(*tags)(function)

小切手にラベルを付けるために、registerに必要な数のタグを渡すことができます。 チェックのタグ付けは、特定のチェックグループのみを実行できるので便利です。 たとえば、互換性チェックを登録するには、次の呼び出しを行います。

from django.core.checks import register, Tags

@register(Tags.compatibility)
def my_check(app_configs, **kwargs):
    # ... perform compatibility checks and collect errors
    return errors

次のように、本番設定ファイルにのみ関連する「デプロイメントチェック」を登録できます。

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

これらのチェックは、check --deployオプションが使用されている場合にのみ実行されます。

registerの最初の引数として呼び出し可能なオブジェクト(通常は関数)を渡すことにより、デコレータではなく関数としてregisterを使用することもできます。

以下のコードは、上記のコードと同等です。

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

フィールド、モデル、マネージャー、およびデータベースのチェック

場合によっては、チェック機能を登録する必要はありません。既存の登録に便乗することができます。

フィールド、モデル、モデルマネージャー、およびデータベースバックエンドはすべて、チェックフレームワークに既に登録されているcheck()メソッドを実装しています。 追加のチェックを追加する場合は、基本クラスの実装を拡張し、必要な追加のチェックを実行して、基本クラスによって生成されたメッセージにメッセージを追加できます。 各チェックを別々のメソッドに委任することをお勧めします。

RangedIntegerFieldという名前のカスタムフィールドを実装している例を考えてみましょう。 このフィールドは、minおよびmax引数をIntegerFieldのコンストラクターに追加します。 ユーザーが最大値以下の最小値を提供することを確認するためのチェックを追加することをお勧めします。 次のコードスニペットは、このチェックを実装する方法を示しています。

from django.core import checks
from django.db import models

class RangedIntegerField(models.IntegerField):
    def __init__(self, min=None, max=None, **kwargs):
        super().__init__(**kwargs)
        self.min = min
        self.max = max

    def check(self, **kwargs):
        # Call the superclass
        errors = super().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().check(**kwargs)
        # ... your own checks ...
        return errors

テストを書く

メッセージは同等です。 これにより、テストを簡単に作成できます。

from django.core.checks import Error
errors = checked_object.check()
expected_errors = [
    Error(
        'an error',
        hint='A hint.',
        obj=checked_object,
        id='myapp.E001',
    )
]
self.assertEqual(errors, expected_errors)