Python 是否可以使用自定义方法/属性重写外键关系 上下文

Python 是否可以使用自定义方法/属性重写外键关系 上下文,python,django,foreign-keys,django-orm,Python,Django,Foreign Keys,Django Orm,我正在重构Django 2.X应用程序,特别是核心模型,CoreModel。有一个包含所有相关表的数据库(Postgres) 重构后,CoreModel的实例将不再存在于Postgres中,它们将存在于Django项目范围之外的其他地方,比如说一些AWS没有SQL数据库服务 还有一些卫星型号将继续在Postgres上运行,但目前将其建模为外键字段 class CordeModel(models.Model): pass class SatelliteModel(models.Model

我正在重构Django 2.X应用程序,特别是核心模型,
CoreModel
。有一个包含所有相关表的数据库(Postgres)

重构后,
CoreModel
的实例将不再存在于Postgres中,它们将存在于Django项目范围之外的其他地方,比如说一些AWS没有SQL数据库服务

还有一些卫星型号将继续在Postgres上运行,但目前将其建模为外键字段

class CordeModel(models.Model):
    pass

class SatelliteModel(models.Model):
    core = models.ForeignKey(CoreModel)

    def some_instance_method(self):
       return self.core.calculate_stuff() # <- override self.core!
有了这个片段,我对
核心
名称有了一个循环依赖,所以这个想法已经过时了

  • 我可以重命名外键:但我更愿意不接触数据库模式。毕竟,我已经在重构应用程序的核心部分,这是一个非常容易出错的过程。如果没有其他选择,我会这么做

  • 我可以将
    @property
    字段重命名为类似于
    current_core
    :这样我就避免了无限递归部分,但这反过来意味着搜索整个代码库以查找关系的引用是一项非常大的任务,而这是中心模型,需要花费大量时间

经过几个小时的研究,我开始怀疑是否可以像我需要的那样,为外键字段重写getter。也许这并不是我想要的,这是一个非常不寻常的用例,但是需求也非常不寻常

非常感谢您提供的任何见解

更新

我忘了添加最关键的信息

大多数的
CoreModel
将在Postgres(历史记录)中删除,但是
CoreModel
s的一小部分将保留下来,并在一段时间后移动。本质上,只有“活动的”
CoreModel
s将保留在Postgres中,但最终所有的都将被移出,而新的
CoreModel
将被创建


这样就排除了将ForeignKey字段更改为整数的可能性。

您可以保留但重命名外键,然后添加具有旧名称的属性

class SatelliteModel(models.Model):
    old_core = models.ForeignKey(CoreModel, null=True, blank=True, on_delete=models.SET_NULL)

    @property
    def core(self):
        try:
            return self.old_core
        except CoreModel.DoesNotExist:
            return aws_client.fetch_core()
这将更改架构中的列名,尽管您可以覆盖列名以防止出现这种情况

old_core = models.ForeignKey(CoreModel, db_column='core_id', null=True, blank=True, on_delete=models.SET_NULL)

可以创建一个子类
ForeignKey
,该子类将按照您的意愿执行,如果这个答案不够,我可以分享一些想法

您仍然需要外键字段吗?你不能用整数字段替换它吗?@IainShelvington谢谢你的提问。我在更新标题下添加了更多信息。这是否需要创建迁移?@Sebastialonso几乎任何解决方案都需要进行迁移,因为
SatelliteModel.core
不再是外键约束?对于迁移了
CoreModel
的实例,获取迁移数据需要旧id吗?旧列设置为什么?
old_core = models.ForeignKey(CoreModel, db_column='core_id', null=True, blank=True, on_delete=models.SET_NULL)