You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django实现交易模型户名同步与账户号转账功能方案咨询

解决方案:账户名同步与转账功能实现

一、账户名同步功能实现

方案1:使用pre_save信号自动同步

利用Django模型信号,在Transaction记录保存前自动根据account_number匹配账户所有者名称,无需在视图/表单中重复编写逻辑:

from django.db.models.signals import pre_save
from django.dispatch import receiver
from .models import Transaction, AccountNum

@receiver(pre_save, sender=Transaction)
def sync_transaction_account_name(sender, instance, **kwargs):
    # 根据输入的账户号查找对应账户记录
    try:
        target_account = AccountNum.objects.get(account_number=instance.account_number)
        # 同步账户所有者名称(这里假设User模型用username作为名称,可根据实际字段调整)
        instance.name = target_account.user.username
    except AccountNum.DoesNotExist:
        # 处理账户不存在的异常情况,可根据业务需求调整
        instance.name = "未知账户"

注意:需要确保信号被正确注册,可在应用的apps.py中添加信号导入,或者在models.py文件末尾导入信号模块。

方案2:在视图/表单层手动处理

如果不想依赖信号,可在创建Transaction的业务逻辑中直接处理名称同步,适合需要更灵活控制的场景:

from django.shortcuts import get_object_or_404
from django.utils import timezone
from .models import Transaction, AccountNum

def create_transaction(request):
    if request.method == 'POST':
        account_num = request.POST.get('account_number')
        amount = request.POST.get('amount')
        
        # 查找目标账户,不存在则返回404
        target_account = get_object_or_404(AccountNum, account_number=account_num)
        
        # 创建Transaction并同步账户名称
        Transaction.objects.create(
            user=request.user,
            account_number=account_num,
            name=target_account.user.username,
            amount=amount,
            created_on=timezone.now()
        )
        # 后续逻辑...

二、转账功能实现

转账涉及两个用户钱包余额的修改,必须保证操作的原子性,避免并发场景下的数据不一致,推荐使用Django的事务机制:

from django.db import transaction
from django.utils import timezone
from decimal import Decimal
from django.http import HttpResponse
from .models import Transaction, AccountNum, Wallet

def handle_transfer(request):
    if request.method == 'POST':
        target_account_num = request.POST.get('account_number')
        transfer_amount = Decimal(request.POST.get('amount'))
        
        # 原子事务:所有操作要么全部成功,要么全部回滚
        with transaction.atomic():
            # 获取当前用户的钱包,不存在则自动创建
            sender_wallet, _ = Wallet.objects.get_or_create(user=request.user)
            
            # 检查余额是否充足
            if sender_wallet.account_balance < transfer_amount:
                return HttpResponse("余额不足,无法完成转账", status=400)
            
            # 查找目标账户对应的用户
            try:
                target_account = AccountNum.objects.get(account_number=target_account_num)
                receiver_user = target_account.user
            except AccountNum.DoesNotExist:
                return HttpResponse("目标账户不存在", status=404)
            
            # 获取接收方钱包,不存在则自动创建
            receiver_wallet, _ = Wallet.objects.get_or_create(user=receiver_user)
            
            # 修改双方余额
            sender_wallet.account_balance -= transfer_amount
            sender_wallet.save()
            
            receiver_wallet.account_balance += transfer_amount
            receiver_wallet.save()
            
            # 创建转账记录
            Transaction.objects.create(
                user=request.user,
                account_number=target_account_num,
                name=receiver_user.username,
                amount=transfer_amount,
                created_on=timezone.now()
            )
        
        return HttpResponse("转账成功")

关键注意事项:

  • 必须使用transaction.atomic()包裹核心逻辑,防止中途出错导致数据异常
  • 处理金额时要使用Decimal类型,避免浮点数精度问题
  • 可在Wallet模型的account_balance字段添加MinValueValidator(0),从模型层限制余额不能为负

内容的提问来源于stack exchange,提问作者Adamu Abdulkarim Dee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 04:29:59