外键更新时Django信号未更新相关模型

时间:2020-04-20 13:28:23

标签: python django django-signals

每次使用信号更改外键时,我都希望更新相关模型,类似于m2m_changed,但对于外键。

用户模型:

class User(AbstractUser):
    balance = models.FloatField(default=0)

交易模式:

class Transaction(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='transactions')
    order = models.OneToOneField('Payment.Order', on_delete=models.CASCADE, related_name='transaction')
    transaction_type = models.CharField(choices=[
        ('transfer', 'Transfer'),
        ('received', 'Received'),
    ], max_length=20, default='transfer')
    created = models.DateTimeField(auto_now_add=True)

我需要在用户下创建新交易时,将其收集到余额中。

信号代码:

@receiver(pre_save, sender=User)
    def collect_transaction(sender, instance, **kwargs):
    balance = instance.transactions.aggregate(Sum('order__price'))
    print(balance)

但是它仅在我从用户模型而不是事务更新时才起作用。

例如,此代码将使信号起作用:

user.transactions.add(transaction)
user.save()

以下代码无法使信号正常工作:

Transaction.objects.create(user=1, order=1, transaction_type='received')

1 个答案:

答案 0 :(得分:1)

仅当保存User模型时,您的信号才会发送。似乎您希望在保存任何Transaction时发送它,因此您应该尝试使用Transaction作为发送者而不是User:

@receiver(post_save, sender=Transaction)
def collect_transactions(sender, instance, **kwargs):
    user = instance.user
    user.balance = user.transactions.aggregate(Sum('order__price'))
    user.save()

关于您保存用户时发出信号的原始示例,我试图考虑一种情况,您将要更新用户但不更新其相关交易,但需要更新余额。如果确实存在这种情况,则最好改写User模型上的save()方法。