制約 (Constraint) リファレンス

このモジュールで定義されたクラスはデータベース制約を作成します。これらはモデルの Meta.constraints オプションで追加されます。

組み込みの制約への参照について

制約は django.db.models.constraints で定義されていますが、利便性のために django.db.models にインポートされています。標準的な規約は from django.db import models を使い、制約を models.<Foo>Constraint と呼ぶことです。

抽象基底クラスにおける制約

制約には常に一意な名前を指定する必要があります。なぜなら、 Meta.constraints オプションはサブクラスに継承され、属性 (name を含む) には毎回全く同じ値が指定されるからです。名前の衝突を避けるために、名前の一部に '%(app_label)s''%(class)s' を含めることができます。これらはそれぞれ小文字のアプリラベルと具体的なモデルのクラス名に置き換えられます。例えば CheckConstraint(check=Q(age__gte=18), name='%(app_label)s_%(class)s_is_adult') のようになります。

制約のバリデーション

制約は モデルのバリデーション の間にチェックされます。

JSONField の制約のバリデーション

JSONField を含む制約は、キー、インデックス、およびパストランスフォームが多くのデータベース固有の注意事項を持っているため、バリデーションエラーを起こさない可能性があります。これは 将来的に完全にサポートされる可能性があります

常に django.db.models のロガーに、 "Got a database error calling check() on …" のようなログメッセージがないことを確認し、正しく検証されていることを確認する必要があります。

BaseConstraint

class BaseConstraint(*name, violation_error_code=None, violation_error_message=None)

すべての制約の基底クラスです。サブクラスは constraint_sql(), create_sql(), remove_sql(), validate() メソッドを実装しなければなりません。

バージョン 5.0 で非推奨: 位置引数のサポートは非推奨になりました。

すべての制約 (constraint) に共通するパラメータは以下の通りです:

name

BaseConstraint.name

制約の名前。制約には常に一意な名前を指定する必要があります。

violation_error_code

New in Django 5.0.
BaseConstraint.violation_error_code

モデルのバリデーション 中に ValidationError が発生した場合に使用されるエラーコードです。デフォルトは None です。

violation_error_message

BaseConstraint.violation_error_message

モデルのバリデーション の実行中に ValidationError が発生した場合に表示されるエラーメッセージです。デフォルトは "Constraint "%(name)s" is violated." です。

validate()

BaseConstraint.validate(model, instance, exclude=None, using=DEFAULT_DB_ALIAS)

モデル model で定義された制約がインスタンス instance で守られているかどうかを検証します。これは、制約が守られていることを確認するために、データベースに対してクエリを実行します。制約を検証するために exclude リストのフィールドが必要な場合、制約は無視されます。

制約に違反した場合は ValidationError を発生させます。

このメソッドはサブクラスで実装する必要があります。

CheckConstraint

class CheckConstraint(*, check, name, violation_error_code=None, violation_error_message=None)

データベースにチェック制約を作成します。

check

CheckConstraint.check

適用したい制約をチェックする Q オブジェクトまたは真偽値 Expression

例えば、CheckConstraint(check=Q(age__gte=18), name='age_gte_18') は年齢フィールドが18歳未満にならないようにします。

Expression order

Q argument order is not necessarily preserved, however the order of Q expressions themselves are preserved. This may be important for databases that preserve check constraint expression order for performance reasons. For example, use the following format if order matters:

CheckConstraint(
    check=Q(age__gte=18) & Q(expensive_check=condition),
    name="age_gte_18_and_others",
)

Oracle について

OracleでNULL許容フィールドに対するチェックを行う場合、validate() がチェック制約の検証と同様に動作するためには、NULL 値を許容する条件を含める必要があります。例えば、age がNULL許容フィールドの場合、以下のようにします:

CheckConstraint(check=Q(age__gte=18) | Q(age__isnull=True), name="age_gte_18")

UniqueConstraint

class UniqueConstraint(*expressions, fields=(), name=None, condition=None, deferrable=None, include=None, opclasses=(), nulls_distinct=None, violation_error_code=None, violation_error_message=None)

データベースにユニーク制約(一意性制約)を作成します。

expressions

UniqueConstraint.expressions

位置引数 *expressions により、式やデータベース関数に対する関数的なユニーク制約を作成できます。

例:

UniqueConstraint(Lower("name").desc(), "category", name="unique_lower_name_category")

これは name フィールドの小文字の値を降順で、category フィールドの値をデフォルトの昇順でユニーク制約を作成します。

関数的なユニーク制約は Index.expressions と同じデータベース制約を持ちます。

fields

UniqueConstraint.fields

制約を適用したい一意な列のセットを表すフィールド名のリスト。

例えば、UniqueConstraint(fields=['room', 'date'], name='unique_booking') は各 room が各 date で一度しか予約できないようにします。

condition

UniqueConstraint.condition

制約を適用したい条件を指定する Q オブジェクト。

例:

UniqueConstraint(fields=["user"], condition=Q(status="DRAFT"), name="unique_draft_user")

これは、各ユーザーが1つの DRAFT しか持たないことを保証します。

これらの condition は Index.condition と同じデータベースの制限を持ちます。

deferrable

UniqueConstraint.deferrable

このパラメータを指定すると、遅延可能なユニーク制約を作成できます。使用可能な値は Deferrable.DEFERRED または Deferrable.IMMEDIATE です。例えば:

from django.db.models import Deferrable, UniqueConstraint

UniqueConstraint(
    name="unique_order",
    fields=["order"],
    deferrable=Deferrable.DEFERRED,
)

デフォルトでは、制約は遅延 (DEFERRED) されません。遅延された制約は、トランザクションが終了するまで実行されません。即時 (IMMEDIATE) 制約は、すべてのコマンドの直後に実行されます。

MySQL, MariaDB, SQLite の場合

MySQL、MariaDB、SQLite のいずれも遅延ユニーク制約をサポートしていないため、遅延ユニーク制約は無視されます。

警告

遅延ユニーク制約は、パフォーマンスへのペナルティ を引き起こす可能性があります。

include

UniqueConstraint.include

ユニークなカバリングインデックス (covering index) に非キー列として含めるフィールド名のリストまたはタプル。これにより、include されたフィールドだけを SELECT するクエリと、 (include)、ユニークなフィールドだけでフィルタリングする(fields) クエリにインデックスだけのスキャンを使用できます。

例:

UniqueConstraint(name="unique_booking", fields=["room", "date"], include=["full_name"])

この設定では、roomdate によるフィルタリング、full_name の SELECT の際にデータをインデックスからのみ取得します。

PostgreSQL以外のデータベースでは、非キー列を持つユニーク制約は無視されます。

非キーカラムは Index.include と同じデータベース制約を持ちます。

opclasses

UniqueConstraint.opclasses

この一意なインデックスに使用する PostgreSQL operator クラス の名前です。カスタム演算子クラスが必要な場合は、インデックスの各フィールドに1つずつ指定しなければなりません。

例:

UniqueConstraint(
    name="unique_username", fields=["username"], opclasses=["varchar_pattern_ops"]
)

これは usernamevarchar_pattern_ops を使用する一意なインデックスを作成します。

opclasses はPostgreSQL以外のデータベースでは無視されます。

nulls_distinct

New in Django 5.0.
UniqueConstraint.nulls_distinct

ユニーク制約の対象となる NULL 値を含む行を、互いに異なる行とみなすかどうかを指定します。デフォルト値は None で、ほとんどのバックエンドで True となるデータベースのデフォルト値を使用します。

例:

UniqueConstraint(name="ordering", fields=["ordering"], nulls_distinct=False)

これは、 ordering カラムに NULL 値を格納できるのは1行だけというユニーク制約を作成します。

nulls_distinct によるユニーク制約は、PostgreSQL 15+ 以外のデータベースでは無視されます。

violation_error_code

New in Django 5.0.
UniqueConstraint.violation_error_code

モデルのバリデーション 中に ValidationError が発生した場合に使用されるエラーコードです。デフォルトは None です。

このコードは、fields を持ち、かつ condition を持たない UniqueConstraint には 使用されません 。このような UniqueConstraint は、Field.uniqueMeta.unique_together で定義された制約と同じエラーコードを持ちます。

violation_error_message

UniqueConstraint.violation_error_message

モデルのバリデーション 中に ValidationError が発生した場合に使用されるエラーメッセージです。デフォルトは BaseConstraint.violation_error_message です。

このメッセージは、fields を持ち、かつ condition を持たない UniqueConstraint には 使用されません 。このような UniqueConstraint は、Field.uniqueMeta.unique_together で定義された制約と同じメッセージを表示します。

Back to Top