有人可以帮我解决这个问题吗?我创建了一个带有两个模型的 django 应用程序。 一种模型是钱包模型,另一种是交易模型。每笔交易都连接到带有 models.ForeignKey 的钱包。我还创建了两个信号,一个用于在进行交易时更新钱包中的加密货币余额(例如 BTC、ETH),另一个信号我想更新 Total_Balance(所有其他余额都转换为美元)。在这里我遇到了一个问题,因为我的信号是 POST_SAVE 并且其中我有一个 save() 方法,它会导致无限循环。我想如果我在第一个信号中做一整件事,它会起作用,但将来我想添加新模型,该模型也将连接到钱包,并且它会弹出我的total_balance,因此我在第三个信号中需要相同的逻辑我最终会在两个信号中得到相同的代码。
我知道我的描述有点困惑。这里有一些代码可以帮助理解它。
我的模型:
class Wallet(models.Model):
name = models.CharField(max_length=50)
total_balance = models.IntegerField(blank=True)
btc_balance = models.DecimalField(max_digits=15, decimal_places=8)
xrp_balance = models.DecimalField(max_digits=15, decimal_places=8)
eth_balance = models.DecimalField(max_digits=15, decimal_places=8)
class Transaction(models.Model):
wallet = models.ForeignKey(Wallet, on_delete=models.CASCADE)
currency_paid = models.CharField(choices=CURRENCY, max_length=3)
amount_paid = models.DecimalField(max_digits=15, decimal_places=8)
currency_recived = models.CharField(choices=CURRENCY, max_length=3)
amount_recived = models.DecimalField(max_digits=15, decimal_places=8)
我的信号:
@receiver(post_save, sender=Transaction)
def create_transaction(sender, instance, created, **kwargs):
if created:
wallet = Wallet.objects.get(name = instance.wallet)
currency_paid = instance.currency_paid
currency_recived = instance.currency_recived
amount_paid = instance.amount_paid
amount_recived = instance.amount_recived
# SUBSTRACK BALANCE
if(currency_paid == 'BTC'):
wallet.btc_balance -= amount_paid
...
# ADDS BALANCE
if(currency_recived == 'BTC'):
wallet.btc_balance += amount_recived
...
wallet.save()
@receiver(post_save, sender=Wallet)
def total_balance_update(sender, instance, created, **kwargs):
if created == False:
btc_price = cryptocompare.get_price('BTC',curr='USD')['BTC']['USD']
xrp_price = cryptocompare.get_price('XRP',curr='USD')['XRP']['USD']
...
btc_balance = float(instance.btc_balance)
xrp_balance = float(instance.xrp_balance)
...
total_balance = instance.total_balance
total_balance = round(btc_balance * btc_price) + round(xrp_balance * xrp_balance) + round(eth_balance * eth_balance)
instance.save()
最佳答案
Wallet
的 post_save
执行 instance.save()
,因此这意味着如果您 .save()
您的钱包
,它将触发钱包
上的post_save
信号,然后再次保存钱包,因此每次信号运行它会再次触发信号来保存钱包。
据我所知,您不需要使用 post_save
信号,因为您似乎没有使用任何仅在对象被保存之后才可用的东西。已保存。您可以使用 pre_save
信号,该信号将在将对象保存到数据库之前运行:
from django.db.models.signals import <b>pre_save</b>
@receiver(<b>pre_save</b>, sender=Wallet)
def total_balance_update(sender, instance, **kwargs):
if instance.pk is not None:
btc_price = cryptocompare.get_price('BTC',curr='USD')['BTC']['USD']
xrp_price = cryptocompare.get_price('XRP',curr='USD')['XRP']['USD']
...
btc_balance = float(instance.btc_balance)
xrp_balance = float(instance.xrp_balance)
...
instance.total_balance = round(btc_balance * btc_price) + round(xrp_balance * xrp_balance) + round(eth_balance * eth_balance)
# <i>no</i> instance.save()
因此,我们不需要保存实例
,因为在运行信号后,Django 将立即开始在数据库中创建/更新记录。
关于python - Django 信号循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64994938/