伪造 Django 模型字段的最简单方法是什么?

What is the simplest way to fake a Django model field?

目前我的 Django 模型如下所示:

class Car(Model):
    horse_power = IntegerField()

我有很多与此类似的模型,它们在整个应用程序中都有使用,也有使用这些模型字段的 DRF 端点序列化程序。当然字段名称在其他模型中是不同的。

但是,horse_power 值以及其他字段不再是 IntegerField,而是另一个 table 的外键,其中包含如下更复杂的信息:

class Car(Model):
    horse_power_complex = OneToOneField(ComplexDataModel, on_delete=CASCADE)

为了避免在操作 Car 模型的每个地方进行大量代码更改,我想保持与以前相同的 getter 和 setter 接口,换句话说,我想要 car.horse_power 到 return 一个从 ComplexDataModel 计算的简单整数,我也想要 car.horse_power = 23 访问 ComplexDataModel 并保存处理后的数据,这样我就不必再检查了整个应用程序以更新所有引用。

重要的是要记住,模型构造函数应该仍然有效,例如,car = Car(horse_power=50)

我试过 python 如下描述符:

class HorsePower:
    def __get__(self, obj, objtype=None):
        return obj.horse_power_complex.get_value()

    def __set__(self, obj, value):
        obj.horse_power_complex.set_value(value)

class Car(Model):
    horse_power = HorsePower()
    horse_power_complex = OneToOneField(ComplexDataModel, on_delete=CASCADE)

这种方法在大多数情况下效果很好,但它无法实例化一个新的 Car 因为构造函数不接受非 django 字段参数。

请不要质疑它为什么要复杂,因为它确实很复杂,汽车和马力只是为了让例子看起来干净而不是用奇怪的科学术语混淆你

使用 property

class Car( Model)
    horse_power_complex = ...

    @property
    def horse_power(self): # getter
        return self.horse_power_complex.get_value()
    @horse_power.setter
    def horse_power( self, value):
        self.horse_power_complex.set_value(value)