Вы не можете использовать метод класса по умолчанию, потому что он требует self
, который не существует, когда вы все еще создаете объект.
Если вам нужно сохранить его в поле (базе данных), переопределить по умолчанию save()
метод или использовать signals
, чтобы изменить поле basis
после создания объекта.Также обратите внимание, что вам нужно пересчитывать базис каждый раз, когда close_price
или spot_price
изменяется, так как значение просто записывается в базу данных.
Вероятно, лучшим решением было бы использовать @property
поэтому для любого, кто будет использовать вашу модель, он будет выглядеть как поле, но он будет динамически вычислять значение на основе текущих данных.
Например, я переопределяю save()
, чтобы вычислить поле basis
.Я установил его как editable=False
, что означает, что он не будет отображаться в формах по умолчанию (и вы не сможете увидеть его в админке!).Вы можете безопасно удалить эту часть, если вы хотите просто посмотреть на значения.Дополнительно я добавляю свойство basis_as_property
.
class Basis(models.Model):
date = models.DateField(primary_key=True)
major_future_contract_close_price = models.FloatField(blank=True)
spot = models.OneToOneField(Spot, on_delete=models.CASCADE)
basis = models.FloatField(editable=False, blank=True)
@property
def basis_as_property(self):
return '%s' % (self.calculate_basis())
def __str__(self):
return str(self.date) if self.date else ''
def save(self, *args, **kwargs):
if not self.basis:
self.basis = self.calculate_basis()
super(Basis, self).save(*args, **kwargs)
def calculate_basis(self):
return abs(self.major_future_contract_close_price - self.spot.spot_price)
Что касается Spot
str repr, я не думаю, что его можно изменить в зависимости от того, где на него ссылаются.Если вы хотите использовать spot_price
, вы можете просто использовать: return str(self.spot_price) if self.spot_price else str(self.date)