Какой самый простой способ подделать поле модели Django?
В настоящее время мои модели Django выглядят следующим образом:
class Car(Model):
horse_power = IntegerField()
У меня много моделей, похожих на эту, они используются по всему приложению, есть сериализаторы конечных точек DRF, использующие эти поля модели. Конечно, имена полей в других моделях отличаются.
Однако, значение horse_power и другие поля уже не IntegerField, а внешний ключ к другой таблице, содержащей более сложную информацию, как показано ниже:
class Car(Model):
horse_power_complex = OneToOneField(ComplexDataModel, on_delete=CASCADE)
Чтобы избежать множества изменений кода в каждом месте, где моделью Car манипулируют, я хотел бы сохранить те же интерфейсы getter и setter, что и раньше, другими словами, я хотел бы, чтобы car.horse_power возвращал простое целое число, вычисленное из 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, поскольку конструктор не принимает аргументы, не относящиеся к jango-полю.
Пожалуйста, не задавайте вопросов о том, почему его нужно сделать сложным, потому что он действительно сложный, автомобиль и лошадиная сила были просто способом сделать пример чистым и не запутать вас странными научными терминами
Используйте свойство
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)