Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django信号环_Python_Django_Django Models_Django Signals - Fatal编程技术网

Python Django信号环

Python Django信号环,python,django,django-models,django-signals,Python,Django,Django Models,Django Signals,有人能帮我解决这个问题吗。我已经创建了一个带有两个模型的django应用程序。 一个模型是钱包模型,另一个是交易模型。每一笔交易都与models.ForeignKey钱包相连。我还创建了两个信号,一个是用于在进行交易时更新钱包中的加密货币余额(如BTC、ETH),另一个是我想要更新总余额(即所有其他余额转换为美元)。这里我有一个问题,因为我的信号是POST_SAVE,其中有一个SAVE()方法,它会导致无穷循环。我想,如果我在第一个信号中做一整件事,它会起作用,但在未来,我想添加新的型号,它也将

有人能帮我解决这个问题吗。我已经创建了一个带有两个模型的django应用程序。 一个模型是钱包模型,另一个是交易模型。每一笔交易都与models.ForeignKey钱包相连。我还创建了两个信号,一个是用于在进行交易时更新钱包中的加密货币余额(如BTC、ETH),另一个是我想要更新总余额(即所有其他余额转换为美元)。这里我有一个问题,因为我的信号是POST_SAVE,其中有一个SAVE()方法,它会导致无穷循环。我想,如果我在第一个信号中做一整件事,它会起作用,但在未来,我想添加新的型号,它也将连接到钱包,它将弹出我的总余额,因此,我需要在第三个信号中使用相同的逻辑,我将在两个信号中使用相同的代码

我知道我的描述有点混乱。下面是一些代码来帮助理解它

我的模型:

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()

您的
钱包的
post\u save
执行一个
实例.save()
,这意味着如果您
.save()
您的
钱包
,它将触发
钱包
上的
post\u save
信号,然后再次保存钱包,因此,每次信号运行时,它都会再次保存钱包,从而触发信号

据我所知,您不需要使用
post_save
信号,因为您似乎不使用仅在保存对象后可用的任何内容。您可以使用将对象保存到数据库之前运行的
pre_save
信号:

from django.db.models.signals import pre_save

@receiver(pre_save, 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)
        # no instance.save()
从django.db.models.signals导入预保存
@接收方(预存,发送方=钱包)
def总余额更新(发送方、实例,**kwargs):
如果instance.pk不是None:
btc_price=cryptocompare.get_price('btc',curr='USD')['btc']['USD']
xrp\u price=cryptocompare.get\u price('xrp',curr='USD')['xrp']['USD']
...
btc_balance=float(实例.btc_balance)
xrp\u balance=float(实例.xrp\u balance)
...
instance.total_balance=四舍五入(btc_balance*btc_price)+四舍五入(xrp_balance*xrp_balance)+四舍五入(eth_balance*eth_balance)
#没有实例。save()

因此,我们不需要保存
实例
,因为在运行信号后,Django将立即开始在数据库中创建/更新记录。

钱包
后期保存
包含一个
实例.save()
。这意味着,如果你
.save()
一个钱包,信号将再次运行保存钱包(从而再次等等)是的,我知道,这就是我寻求帮助的原因。我能做些什么?谢谢,这很有效。但是对于记录,您需要删除“created”参数,因为pre_save确实需要它。@bazzuk123:aahh是的。您可以使用
instance.pk而不是None
。将被更新的记录有一个
.pk
不是
None