我有一个看起来像这样的django模型...
class Account(models.Model):
account_name = models.CharField(max_length=100)
deposited_amount = models.PositiveIntegerField(default=0)
opening_balance = models.IntegerField(default=0)
current_balance = models.CharField(max_length=9)
在我的admin.py
文件中,我将current_balance
字段设置为只读。我希望当前余额为deposited_amount
和opening_balance
的总和,因此我已经实现了一个信号来尝试处理该问题……
@receiver(post_save, sender=Account, dispatch_uid="update_current_balance")
def update_current_balance(sender, **kwargs):
created = kwargs['created']
instance = kwargs['instance']
if created:
instance.current_balance = F('deposited_amount') + F('opening_balance')
创建新帐户效果很好,但current_balance不会更新。我在这里想念什么?
此外,我在考虑如果存款金额或期初余额已更新,我也需要更新当前余额,所以我应该删除if created
支票,还是创建另一个信号? ?
答案 0 :(得分:1)
您需要在信号中调用instance.save
来更新实例。以下代码可以解决您的问题
@receiver(post_save, sender=Account, dispatch_uid="update_current_balance")
def update_current_balance(sender, **kwargs):
created = kwargs['created']
instance = kwargs['instance']
if created:
instance.current_balance = F('deposited_amount') + F('opening_balance')
instance.save()
elif 'deposited_amount' in kwargs['updated_fields']:
# do your work and don't forget to call .save()
或者您需要在pre_save
信号中执行此操作。
我们将有三个帐户。 User
将保留有关帐户所有者的信息,UserAccount
将保留有关用户当前有多少钱的信息。 TransactionLog
将所有交易保留在我们的系统中。这样
Truth Table
。如果用户不满,我的帐户中应该有很多钱(目前未显示)。我们可以给他发言。 首先,我们应该有UserModel
。这可以是Default Django User Mode
link,也可以扩展AbstractBaseUser
模型link
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
balance = models.BigIntegerField(default=0)
class TransactionLog(models.Model):
CREDIT = 'CREDIT'
DEBIT = 'DEBIT'
OPENING_ACCOUNT = 'OPENING_ACCOUNT'
DEPOSITE_INTO_ACCOUNT = 'DEPOSITE_INTO_ACCOUNT'
WITHDRAW_FROM_ACCOUNT = 'WITHDRAW_FROM_ACCOUNT'
UNKNOWN = 'UNKNOWN'
TRANSACTION_TYPES = (
(CREDIT, 'credit'),
(DEBIT, 'debit'),
)
REASON_TYPES = ((OPENING_ACCOUNT, 'OPENING_ACCOUNT'), (DEPOSITE_INTO_ACCOUNT,
'deposite_into_account'),
(WITHDRAW_FROM_ACCOUNT, 'withDRAW_FROM_ACCOUNT'), (UNKNOWN, 'unknown'))
type = models.CharField(choices=TRANSACTION_TYPES, max_length=6)
reason = models.CharField(
choices=REASON_TYPES, max_length=255, default=UNKNOWN)
timestamp = models.DateTimeField(auto_now_add=True)
amount = models.IntegerField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
现在,对于系统中TransactionLog
中的每个条目,我们将触发一个信号。基于reason
和type
,我们将更新Account
。我必须提到opening account
和deposite first amount
应该有所不同。 TransactionLog
表中必须有其他条目。 TransactionLog
是我们的Truth Log Table
。这应该记录每个transaction
。
我们的信号将像
from .models import Account, TransactionLog
@receiver(post_save, sender=TransactionLog, dispatch_uid="transaction log entry")
def update_user_account(sender, instance, **kwargs):
if instance.reason == TransactionLog.OPENING_ACCOUNT:
Account.objects.create(user=instance.user_id, balance=instance.amount)
else:
user_account = Account.objects.get(user=instance.user_id)
if instance.type == TransactionLog.CREDIT:
user_account.balance = F('balance') + instance.amount
else: # For Debit
user_account.balance = F('balance') - instance.amount
user_account.save()
我想补充的一件事。由于这是我们模型中与交易相关的插入,因此TransactionLog
和Account
中的两个条目都应具有transaction_automic
链。甚至我们都可以在模型设置link中执行此操作,以便我们所有的视图/ HTTP_REQUEST_API都应具有该功能。
希望这会有所帮助。