参考模型层中的相关模型字段
Posted
技术标签:
【中文标题】参考模型层中的相关模型字段【英文标题】:Refer related model field in model layer 【发布时间】:2019-09-14 10:53:29 【问题描述】:我尝试在 django 模型层的模型“基础”中引用模型“现货”的“现货价格”,我该如何管理?
我设计了 view.py 来自动渲染模板。所以我无法修改任何 view.py 来选择像“models.B.objects.get().field”这样的数据。
还有,str设置为表示日期,所以,在django后台管理中,'spot'字段显示会是'date'格式,怎么改成'spot_price' ?
模型现货
class Spot(models.Model):
date = models.DateField(primary_key=True)
spot_price = models.FloatField(blank=True, null=True)
def __str__(self):
return str(self.date) if self.date else ''
需要按日期引用模型Spot的spot_price,因为日期是唯一的但spot_price不是
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(default=calculate_basis)
def __str__(self):
return str(self.date) if self.date else ''
def calculate_basis(self):
return abs(self.major_future_contract_close_price -
self.spot.spot_price)
我预计 Basis.query.data 会喜欢“日期:2019-04-25,major_future_contract_close_price:100.0,现货:96.5,基础:3.5”
【问题讨论】:
您想在Basis
中仅为OneToOneField
更改Spot
str 吗? calculate_basis
需要参考spot_price
吗?
没错,我在这个Basis
模型中只需要spot_price
,而在其他模型中,我更喜欢date
作为str。 calculate_basis
需要 spot_price
模型中的 Spot
字段。
calculate_basis
在同一 date
中同时引用 spot_price
和 major_future_contract_close_price
【参考方案1】:
你不能默认使用类方法,因为它需要self
,当你还在创建对象时,它并不存在。
如果您需要将其存储在字段(数据库)中,override default save()
method 或在创建对象后使用 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)
【讨论】:
对不起,我还不熟悉***,以为您可能没有看到我的回复。我只在这个Basis
模型中使用spot_price
,而在其他模型中,我更喜欢date
作为str。 calculate_basis
方法要求spot_price
和major_future_contract_close_price
具有相同的date
以上是关于参考模型层中的相关模型字段的主要内容,如果未能解决你的问题,请参考以下文章