Абстрактная модель в Django с ForeignKey наследуется не так, как ожидалось

При попытке выполнить makemigrations в моем приложении Django я сталкиваюсь с ошибками, связанными с круговыми ссылками. Я определил абстрактный класс A, который наследуется от models.Model, и два дочерних класса B и C. Однако, похоже, я допускаю ошибки в отношениях между этими классами. Вот соответствующий код:

class A(models.Model):
    class Meta:
        abstract = True
    id = models.AutoField(primary_key=True)
    
    z = models.ForeignKey(Z, on_delete=models.CASCADE, related_name="relateds")


class B(A):
    algo = models.CharField(max_length=32, default="")


class C(A):
    foo = IntegerField()

Я столкнулся со следующей ошибкой:

z.B.z: (fields.E305) Имя обратного запроса для 'z.B.z' конфликтует с именем обратного запроса для 'z.C.z'.

Любая помощь или предложения по решению этой проблемы будут очень признательны!

The reason this does not work is because you have two real models B and C, each with a ForeignKey to Z, and that Z thus can not have both with the same value for related_name=… [Django-doc]. Why? Because the related name is the name of the relation in reverse. So from Z to B or C. So if you would query my_z.relateds.all(), then what model should it target? B or C?

Вы можете решить эту проблему, поставив related_name=… в зависимость от имени класса, в котором он определен, например:

class A(models.Model):
    z = models.ForeignKey(Z, on_delete=models.CASCADE, related_name='%(class)ss')

    class Meta:
        abstract = True

или с:

class A(models.Model):
    z = models.ForeignKey(Z, on_delete=models.CASCADE, related_name='%(class)s_set')

    class Meta:
        abstract = True

но именно так поступает Django, если вы не указываете связанное имя самостоятельно, что может быть лучшим вариантом:

class A(models.Model):
    z = models.ForeignKey(Z, on_delete=models.CASCADE)  # 🖘 no related_name=…

    class Meta:
        abstract = True
Вернуться на верх