Многотабличное наследование в 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.

Вернуться на верх