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

Django多事务转账报错:UserBalanceChange与int无法执行+运算

Django多用户转账功能报错修复

问题说明

在Django中实现多用户转账:买家支付的金额按80%分给卖家,20%分给管理员。仅涉及两位用户时代码正常运行,加入第三位用户后触发错误:Error 'unsupported operand type(s) for +: 'UserBalanceChange' and 'int''。

现有代码

views.py

from django.db import transaction
from django.http import HttpResponse
from django.shortcuts import render
from .models import UserBalanceChange

@transaction.atomic()
def transaction_file(request):
    if request.method == "POST":
        try:
            buyer = request.POST.get('buyer')
            seller = request.POST.get('seller')
            admin = request.POST.get('admin')
            amount = request.POST.get('amount')

            buyer_obj = UserBalanceChange.objects.get(user=buyer)
            seller_obj = UserBalanceChange.objects.get(user=seller)
            admin_obj = UserBalanceChange.objects.get(user=admin)

            with transaction.atomic():
                buyer_obj.amount -= int(0.8*int(amount))
                buyer_obj.save()

                seller_obj.amount += int(0.8*int(amount))
                seller_obj.save()

                with transaction.atomic():
                    buyer_obj.amount -= int(0.2 * int(amount))
                    buyer_obj.save()

                    admin_obj = admin_obj + int(0.2 * int(amount))
                    admin_obj.save()
                return HttpResponse('Транзакция успешно проведена')

        except Exception as e:
            print(e)
            return HttpResponse('Что-то пошло не так!(')

    return render(request,'chat/files/chattransaction.html')

models.py

from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone

class UserBalanceChange(models.Model):
    user = models.ForeignKey(User,on_delete = models.CASCADE, related_name='balance_changes')
    amount = models.DecimalField(verbose_name='Amount', default=0, max_digits=18, decimal_places=2)
    datetime = models.DateTimeField(verbose_name='date', default=timezone.now)

    def __str__(self):
        return f'{self.user.username}'

HTML模板

<form method="POST" style="width: 50%;">
    {% csrf_token %}
    <form method="post">
        <div class="form-group">
            <label>Покупатель</label>
            <input class="form-control" name="buyer" type="text" placeholder="Покупатель">
        </div>
        <div class="form-group">
            <label>Продавец</label>
            <input class="form-control" name="seller" type="text" placeholder="Продавец">
        </div>
        <div class="form-group">
            <label>Админ</label>
            <input class="form-control" name="admin" type="text" placeholder="Админ">
        </div>
        <div class="form-group">
            <label>Цена</label>
            <input class="form-control" name="amount" type="text" placeholder="Цена">
        </div>
        <button type="submit" class="btn btn-primary">Купить</button>
    </form>
</form>

错误原因

报错行admin_obj = admin_obj + int(0.2 * int(amount))中,admin_obj是UserBalanceChange模型实例,不能直接与整数相加。正确操作应该是修改实例的amount属性,和前面处理买家、卖家余额的逻辑一致。

另外还有两处优化点:

  1. 嵌套的transaction.atomic()无必要,外层已经用装饰器开启了原子事务,所有操作会作为一个整体提交/回滚。
  2. 用int()处理金额会丢失精度,建议用Decimal类型计算,匹配模型中的DecimalField。

修正后的代码

修正后的views.py

from django.db import transaction
from django.http import HttpResponse
from django.shortcuts import render
from decimal import Decimal
from .models import UserBalanceChange

@transaction.atomic()
def transaction_file(request):
    if request.method == "POST":
        try:
            buyer = request.POST.get('buyer')
            seller = request.POST.get('seller')
            admin = request.POST.get('admin')
            amount = Decimal(request.POST.get('amount'))

            buyer_obj = UserBalanceChange.objects.get(user=buyer)
            seller_obj = UserBalanceChange.objects.get(user=seller)
            admin_obj = UserBalanceChange.objects.get(user=admin)

            # 计算分配金额
            seller_amount = amount * Decimal('0.8')
            admin_amount = amount * Decimal('0.2')

            # 扣减买家余额
            buyer_obj.amount -= amount
            buyer_obj.save()

            # 增加卖家余额
            seller_obj.amount += seller_amount
            seller_obj.save()

            # 增加管理员余额
            admin_obj.amount += admin_amount
            admin_obj.save()

            return HttpResponse('Транзакция успешно проведена')

        except Exception as e:
            print(e)
            return HttpResponse('Что-то пошло не так!(')

    return render(request,'chat/files/chattransaction.html')

修正后的HTML模板(移除嵌套form)

<form method="POST" style="width: 50%;">
    {% csrf_token %}
    <div class="form-group">
        <label>Покупатель</label>
        <input class="form-control" name="buyer" type="text" placeholder="Покупатель">
    </div>
    <div class="form-group">
        <label>Продавец</label>
        <input class="form-control" name="seller" type="text" placeholder="Продавец">
    </div>
    <div class="form-group">
        <label>Админ</label>
        <input class="form-control" name="admin" type="text" placeholder="Админ">
    </div>
    <div class="form-group">
        <label>Цена</label>
        <input class="form-control" name="amount" type="text" placeholder="Цена">
    </div>
    <button type="submit" class="btn btn-primary">Купить</button>
</form>

内容的提问来源于stack exchange,提问作者Xrystik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:50:24