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)

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