制約 (Constraint) リファレンス

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

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

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

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

You must always specify a unique name for the constraint. As such, you cannot normally specify a constraint on an abstract base class, since the Meta.constraints option is inherited by subclasses, with exactly the same values for the attributes (including name) each time. To work around name collisions, part of the name may contain '%(app_label)s' and '%(class)s', which are replaced, respectively, by the lowercased app label and class name of the concrete model. For example CheckConstraint(condition=Q(age__gte=18), name='%(app_label)s_%(class)s_is_adult').

制約のバリデーション

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

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(*, condition, name, violation_error_code=None, violation_error_message=None)[ソース]

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

condition

CheckConstraint.condition

A Q object or boolean Expression that specifies the conditional check you want the constraint to enforce.

For example, CheckConstraint(condition=Q(age__gte=18), name='age_gte_18') ensures the age field is never less than 18.

式の順序

Q の引数の順番は必ずしも保持されるわけではありませんが、 Q 式の順番自体は保持されます。これは、パフォーマンス上の理由からチェック制約式の順序を保持するデータベースにとって、重要なことです。例えば、順序が重要な場合は以下の形式を使用します。

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

Oracle < 23c

Checks with nullable fields on Oracle < 23c must include a condition allowing for NULL values in order for validate() to behave the same as check constraints validation. For example, if age is a nullable field:

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

バージョン 5.1 で非推奨: The check attribute is deprecated in favor of condition.

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