python - 更新外键时,Django 信号不会更新相关模型

标签 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')

最佳答案

只有当 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()

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

关于python - 更新外键时,Django 信号不会更新相关模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61323653/

相关文章:

python - 以有效的方式从列表中消除特定元素的函数

python - pk__in 在 Django 中是什么意思?

mysql - 对历史上未被认可的 django 进行唯一的约束

django - 响应 Django 中的模型更改?

python - 是否可以在 Django 中查询查询对象?

Python 正则表达式在>之后使用正向lookbehind进行匹配

python - 从 psycopg2 获取字典

python - Django 模型 : use field from foreign key

python - 如何在django post_save监听器中获取请求对象

python - Django:无法从 ForwardManyToOneDescriptor (ForeignKey) 获取模型实例