不同Django应用下同名模型继承公共基类迁移报错如何解决?
报错原因
你当前使用Django默认的多表继承方案,app1.Task和app2.Task都继承自BasicTask时,Django会自动为每个子类生成一个指向父类的一对一关联字段basictask_ptr,两个子类生成的反向访问器默认名称重复,因此触发冲突。BasicFile如果后续有多个子类也会触发同类问题。
解决方案
方案1:将父类改为抽象模型(推荐,符合你的需求)
你需要两个应用的Task、File表完全独立,不需要共用父表存储数据,直接将BasicTask和BasicFile设为抽象基类即可,抽象基类不会生成独立数据表,所有字段会自动映射到子类的表中,不会生成xxx_ptr关联字段,从根源避免冲突。
修改main.models代码如下:
class BasicTask(models.Model): name = models.TextField() priority = models.IntegerField() status = models.IntegerField(default=0) user = models.ForeignKey( CustomUser, on_delete=models.CASCADE, null=True, related_name='+') def __str__(self): return f"{self.id}. {self.name}" class Meta: abstract = True # 新增这行,声明为抽象基类 class BasicFile(models.Model): unique_id = models.TextField() status = models.IntegerField(default=0) user = models.ForeignKey( CustomUser, on_delete=models.CASCADE, null=True, related_name='+') content = models.TextField() def __str__(self): return f"{self.id}. {self.unique_id}" class Meta: abstract = True # 新增这行,声明为抽象基类
方案2:保留多表继承,手动指定反向关联名称
如果你确实需要保留BasicTask、BasicFile对应的独立父表(比如需要统一查询所有子类的公共字段),可以在父类中使用动态占位符生成不重复的related_name,修改main.models代码如下:
class BasicTask(models.Model): name = models.TextField() priority = models.IntegerField() status = models.IntegerField(default=0) user = models.ForeignKey( CustomUser, on_delete=models.CASCADE, null=True, related_name='+') def __str__(self): return f"{self.id}. {self.name}" class Meta: default_related_name = "%(app_label)s_%(class)s" # 用应用名和类名动态生成反向访问器名称 class BasicFile(models.Model): unique_id = models.TextField() status = models.IntegerField(default=0) user = models.ForeignKey( CustomUser, on_delete=models.CASCADE, null=True, related_name='+') content = models.TextField() def __str__(self): return f"{self.id}. {self.unique_id}" class Meta: default_related_name = "%(app_label)s_%(class)s" # 用应用名和类名动态生成反向访问器名称
后续操作
修改完成后,删除之前生成的冲突迁移文件,重新执行python manage.py makemigrations即可正常生成迁移文件。
内容的提问来源于stack exchange,提问作者leach
相关产品推荐
相关产品推荐

