вам нужно позвонить 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
сигнале.
Обновить для TransactionLog
У нас будет три аккаунта.User
будет хранить информацию о владельце Аккаунта, UserAccount
будет хранить информацию о том, сколько денег у пользователя в данный момент.TransactionLog
будет хранить все транзакции в нашей системе.Так что
- Это может работать как
Truth Table
.Если пользователь заявляет, что на моем счете должно быть много денег, которые в данный момент не отображаются.Мы можем дать ему заявление. - Мы можем разделить ответственность.Каждая модель должна служить одной ответственности.
Возможные модели
Сначала у нас должно быть UserModel
.Это может быть Default Django User Mode
ссылка Или мы можем расширить AbstractBaseUser
модель ссылка
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
.Даже мы можем сделать это в наших настройках модели ссылка , чтобы все наши представления / HTTP_REQUEST_API имели это.
Надеюсь, это поможет.