約束條件參考¶
此模組中定義的類別會建立資料庫約束條件。它們會被新增到模型的 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(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 版本起已棄用:已棄用傳遞位置引數的支援。
所有約束條件都有以下共通參數
name
¶
- BaseConstraint.name¶
約束條件的名稱。您必須始終為約束條件指定唯一的名稱。
violation_error_code
¶
- BaseConstraint.violation_error_code¶
在模型驗證期間引發 ValidationError
時使用的錯誤代碼。預設值為 None
。
violation_error_message
¶
- BaseConstraint.violation_error_message¶
在模型驗證期間引發 ValidationError
時使用的錯誤訊息。預設值為 "Constraint “%(name)s” is violated."
。
validate()
¶
驗證在 model
上定義的約束條件,是否在 instance
上被遵守。這會對資料庫執行查詢,以確保約束條件被遵守。如果驗證約束條件需要 exclude
清單中的欄位,則會忽略該約束條件。
如果違反約束條件,則會引發 ValidationError
。
此方法必須由子類別實作。
CheckConstraint
¶
- class CheckConstraint(*, condition, name, violation_error_code=None, violation_error_message=None)[原始碼]¶
在資料庫中建立檢查約束條件。
condition
¶
- CheckConstraint.condition¶
Q
物件或布林值Expression
,用於指定您想要約束條件強制執行的條件檢查。
例如,CheckConstraint(condition=Q(age__gte=18), name='age_gte_18')
可確保年齡欄位永遠不小於 18。
運算式順序
Q
引數順序不一定會被保留,但是 Q
運算式本身的順序會被保留。對於為了效能而保留檢查約束條件運算式順序的資料庫而言,這可能很重要。例如,如果順序很重要,請使用以下格式
CheckConstraint(
condition=Q(age__gte=18) & Q(expensive_check=condition),
name="age_gte_18_and_others",
)
Oracle < 23c
Oracle < 23c 上具有可為 null 欄位的檢查必須包含允許 NULL
值的條件,以便 validate()
的行為與檢查約束條件驗證相同。例如,如果 age
是可為 null 的欄位
CheckConstraint(condition=Q(age__gte=18) | Q(age__isnull=True), name="age_gte_18")
自 5.1 版本起已棄用:已棄用 check
屬性,改用 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')
確保每個房間在每個日期只能被預訂一次。
condition
¶
- UniqueConstraint.condition¶
一個 Q
物件,指定您希望約束強制執行的條件。
例如:
UniqueConstraint(fields=["user"], condition=Q(status="DRAFT"), name="unique_draft_user")
確保每個使用者只有一個草稿。
這些條件與 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,
)
預設情況下,約束不會延遲。延遲的約束將在事務結束時才被強制執行。立即約束將在每個命令之後立即強制執行。
MySQL、MariaDB 和 SQLite。
由於 MySQL、MariaDB 和 SQLite 都不支援可延遲的唯一約束,因此將忽略它們。
警告
延遲的唯一約束可能會導致 效能上的損失。
include
¶
- UniqueConstraint.include¶
要包含在覆蓋唯一索引中作為非鍵欄位的欄位名稱的列表或元組。這允許僅使用索引掃描來查詢僅選擇包含的欄位 (include
),並且僅按唯一欄位 (fields
) 進行篩選。
例如:
UniqueConstraint(name="unique_booking", fields=["room", "date"], include=["full_name"])
將允許根據 room
和 date
進行篩選,同時選取 full_name
,並且僅從索引中提取資料。
除了 PostgreSQL 之外,其他資料庫將忽略具有非鍵欄位的唯一約束。
非鍵欄位與 Index.include
具有相同的資料庫限制。
opclasses
¶
- UniqueConstraint.opclasses¶
要用於此唯一索引的 PostgreSQL 運算子類別的名稱。如果您需要自訂運算子類別,則必須為索引中的每個欄位提供一個。
例如:
UniqueConstraint(
name="unique_username", fields=["username"], opclasses=["varchar_pattern_ops"]
)
會使用 varchar_pattern_ops
在 username
上建立一個唯一索引。
除了 PostgreSQL 之外,其他資料庫將忽略 opclasses
。
nulls_distinct
¶
- UniqueConstraint.nulls_distinct¶
唯一約束涵蓋的包含 NULL
值的列是否應被視為彼此不同。預設值為 None
,它會使用資料庫預設值,大多數後端為 True
。
例如:
UniqueConstraint(name="ordering", fields=["ordering"], nulls_distinct=False)
建立一個唯一約束,僅允許一個列在 ordering
欄位中儲存 NULL
值。
除了 PostgreSQL 15+ 之外,其他資料庫將忽略具有 nulls_distinct
的唯一約束。
violation_error_code
¶
- UniqueConstraint.violation_error_code¶
在模型驗證期間引發 ValidationError
時使用的錯誤代碼。預設值為 None
。
此程式碼「不適用於」具有 fields
且沒有 condition
的 UniqueConstraint
。此類 UniqueConstraint
的錯誤程式碼與使用 Field.unique
或在 Meta.unique_together
中定義的約束相同。
violation_error_message
¶
- UniqueConstraint.violation_error_message¶
在 模型驗證 期間引發 ValidationError
時使用的錯誤訊息。預設為 BaseConstraint.violation_error_message
。
此訊息不適用於具有UniqueConstraint
,且帶有fields
但沒有condition
的約束。這類UniqueConstraint
會顯示與使用Field.unique
或在Meta.unique_together
中定義的約束相同的訊息。