Многотабличное наследование в Django - убедитесь, что существует только один ребенок (CheckConstraint)
Как убедиться, что родительский объект имеет только один дочерний/тип?
class Property(...):
class Meta:
abstract = False
class Flat(Property):
pass
class House(Property):
pass
class Land(Property):
pass
Я хочу, чтобы каждый объект свойства не имел ни одного или не более одного дочернего объекта. Это может быть либо flat
, house
, либо land
(или null
).
Возможно ли создать для этого ограничение в БД?
Моя идея состояла в том, чтобы создать ограничение, которое проверяет:
class Meta:
constraints = [
models.CheckConstraint(check=Q(Q(flat__isnull=True) & Q(house__isnull=True))
|
Q(Q(flat__isnull=True) & Q(land__isnull=True))
|
Q(Q(house__isnull=True) & Q(land__isnull=True)),
name="constraint")]
Но, видимо, на уровне БД таких полей нет (вы можете получить flat
с помощью геттера property.flat
в Django, но не в БД)
РЕДАКТИРОВАНИЕ:
properties.Property: (models.E012) 'constraints' refers to the nonexistent field 'flat'.
Но, видимо, на уровне БД таких полей нет (в Django можно получить плоские поля с помощью геттера
.property.flat
, но не в БД)
Это правильно: Django добавляет свойство к модели Property
для ленивой загрузки связанного объекта Flat
и будет делать запрос для этого, но нет поля базы данных с именем flat
: это просто обратный запрос, где Django в основном запрашивает с:
SELECT * FROM app_name_flat WHERE property_ptr=pk
с pk
первичным ключом объекта property
. Это делает запрос.
Ограничение CHECK
[w3-schools] распространяется только на строку : оно не может просматривать другие строки и не может просматривать другие таблицы. Таким образом, он не может ограничивать другие таблицы и поэтому ограничен. Например, он может запретить одному столбцу иметь определенное значение на основе значения другого столбца в той же строке (записи), но это то, насколько далеко обычно заглядывает ограничение CHECK
.