Django: Как обеспечить соблюдение UniqueConstraint в родительской и дочерней моделях
Допустим, у меня есть следующие модели:
class ParentModel(models.Model):
parent_field_1 = models.CharField(max_length=10)
parent_field_2 = models.CharField(max_length=10)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['parent_field_1', 'parent_field_2', 'child_field_2'],
name='unique_parent_example'
)
]
class ChildModel(ParentModel):
child_field_1 = models.CharField(max_length=10)
child_field_2 = models.CharField(max_length=10)
Я хочу использовать ParentModel'UniqueConstraint, но применить дополнительное поле в ChildModel'UniqueConstraint. Я знаю, что это невозможно, но чтобы помочь визуализировать идею, я бы хотел сделать что-то вроде этого:
class ChildModel(ParentModel):
[.. fields ..]
class Meta:
constraints = [
models.UniqueConstraint(
fields=['parentmodel', 'child_field_2'],
name='unique_child_example'
)
]
Почти так же, как я строю уникальное ограничение как наследование.
Как я могу это сделать?
Наследование нескольких таблиц (как вы используете) использует отношения один к одному. Это означает, что каждый родитель может иметь только одного ребенка и наоборот
это неявно приведет в действие уникальность детей, поскольку они могут относиться только к одному родителю, поэтому если родитель уникален, то и ребенок будет уникален.
для предотвращения дублирования информации в дочерней модели просто примените мета-ограничения как в родительской или сделайте unique=True в полях
Если вы хотите, чтобы только некоторые колонки в дочерней модели были уникальными для родительской - то, как вы уже сказали, это невозможно. Чтобы достичь чего-то подобного, вам нужно разделить дочернюю модель на несколько моделей - уникальный материал останется в дочерней модели, которая наследуется от родительской, а другой материал будет находиться в другой модели, которая имеет связь по внешнему ключу с родительской
вот что я бы сделал, основываясь на том, что вы рассказали:
class ParentModel(models.Model):
parent_field_1 = models.CharField(max_length=10)
parent_field_2 = models.CharField(max_length=10)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['parent_field_1', 'parent_field_2'],
name='unique_parent'
)
]
class ChildModel(ParentModel):
child_field_2 = models.CharField(max_length=10, unique=true)
# this being unique means that only one parent can have a child like this
class UnInheritedChild(models.Model):
child_field_1 = models.CharField(max_length=10)
parent = models.ForeignKey(ParentModel, on_delete=models.CASCADE)