Абстрактная модель в 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