[英]After performing arithmetic operations within a django model, how can I update the value of an integer in my model using the new value I obtained?
The code I have below was derived from this Question我下面的代码来自这个问题
class CryptoData(models.Model):
currency = models.CharField(max_length=20, choices=currency_choices, default='BTC')
amount = models.IntegerField()
price_with_amount = 1
def calculate_price(self):
if self.currency == "BTC":
currency_price = get_crypto_price("bitcoin")
elif self.currency == "ETH":
currency_price = get_crypto_price("ethereum")
elif self.currency == "UNI":
currency_price = get_crypto_price("uniswap")
elif self.currency == "ADA":
currency_price = get_crypto_price("cardano")
elif self.currency == "BAT":
currency_price = get_crypto_price("basic attention token")
price_with_amount = currency_price * self.amount
return price_with_amount
def save(self,*args,**kwargs):
self.price_with_amount = self.calculate_price()
super().save(*args, **kwargs)
class Meta:
verbose_name_plural = "Crypto Data"
def __str__(self):
return f'{self.currency}-{self.amount}-{self.price_with_amount}'
Basically, I want to multiply the user input, amount, by the price I obtain using my get_crypto_price function (I have confirmed that the get_crypto_price function works).基本上,我想将用户输入的金额乘以我使用 get_crypto_price 函数获得的价格(我已经确认 get_crypto_price 函数有效)。 After saving self.price_with_amount, I want to return it in my str method then pass it to my views.py to be used in my HTML.
保存 self.price_with_amount 后,我想在我的str方法中返回它,然后将它传递给我的 views.py 以在我的 HTML 中使用。 When I give price_with_amount a value of 1 for example, as I did in my code, it gets passed and works fine in my HTML.
例如,当我将 price_with_amount 的值设为 1 时,就像我在代码中所做的那样,它会通过并在我的 HTML 中正常工作。 What I'm trying to do is change the value of price_with_amount to the obtained values in the method calculate_price.
我想要做的是将 price_with_amount 的值更改为方法calculate_price 中获得的值。 How can this be done while keeping the methods I currently have?
如何在保持我目前拥有的方法的同时做到这一点?
Thanks :)谢谢 :)
If you really want to save it to the database, you could make the field a models.FloatField
with the editable=False
argument, so that it doesn't appear in the form for the user to edit.如果你真的想把它保存到数据库中,你可以使用
editable=False
参数使该字段成为一个models.FloatField
,这样它就不会出现在用户编辑的表单中。 Then the rest of your code should work as is.然后您的其余代码应该按原样工作。
But...但...
Since price_with_amount
is a dynamic value that's based on the current price, via the get_crypto_price
function, it doesn't seem like a good idea to save it.由于
price_with_amount
是基于当前价格的动态值,因此通过get_crypto_price
函数保存它似乎不是一个好主意。
Instead, you could calculate the value on-the-fly using a @property
.相反,您可以使用
@property
即时计算值。 A property
is an instance method that you can use as if it were a regular attribute. property
是一个实例方法,您可以像使用常规属性一样使用它。
Your code could be rewritten like this:你的代码可以这样重写:
class CryptoData(models.Model):
currency = models.CharField(...)
amount = models.IntegerField()
...
@property
def price_with_amount(self):
return self.calculate_price()
def __str__(self):
return f'{self.currency}-{self.amount}-{self.price_with_amount}'
With this implementation, you can always access the price_with_amount
property on a CryptoData
instance, and as long as it has the currency
and amount
values, it will show the value calculated on demand.使用此实现,您始终可以访问
CryptoData
实例上的price_with_amount
属性,只要它具有currency
和amount
值,它就会显示按需计算的值。
>>> crypto = CryptoData(currency="ETH", amount=10)
>>> crypto.price_with_amount
22718.20
>>> crypto.save()
# It still behaves as expected after fetching it from the db
>>> CryptoData.objects.get(id=crypto.id).price_with_amount
22718.20
# You can use the property just like you would a regular attribute
>>> if crypto.price_with_amount > 1000:
print("foobar")
foobar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.