是否可以用自定义 method/property 覆盖外键关系

is it possible to override a foreign key relation with a custom method/property

上下文

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

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

还有几个卫星模型 SateliteModelCoreModel 将继续存在于 Postgres 上,但 CoreModel 目前被建模为外键字段。

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!

问题

代码中提到了CoreModel关系,我一直没能成功解决这个问题。

我第一个天真的方法是实现一个 @property getter 方法,这样我就有足够的灵活性来做类似的事情:

@property
def core(self):
    try:
       # ORM
       return self.core
    except CoreNotFound:
       # External datastore
       return aws_client.fetch_core()

有了这个代码片段,我对 core 名称产生了循环依赖,所以这个想法已经过时了。

经过几个小时的研究,我开始怀疑是否可以为外键字段覆盖 getter 的概念,因为我需要它。也许这不是我要找的,这是一个非常不寻常的用例,但要求也很不寻常。

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

更新

我忘了添加最重要的信息。

大多数 CoreModel 将被删除用于 Postgres(历史的),但 CoreModel 的一小部分将保留并在一段时间后移动。本质上,只有 "active" CoreModel 会保留在 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 的子类,它会按照您的意愿执行,如果这个答案还不够,我可以分享一些想法