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

如何在Django应用中实现数值增减运算并允许用户修改CharField值

Django虚拟货币系统+CharField字段修改实现方案

一、虚拟货币系统实现

1. 模型设计

扩展用户模型添加虚拟货币余额(用DecimalField规避浮点精度问题),同时创建商品模型:

# models.py
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    balance = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0.00,
        verbose_name="虚拟货币余额"
    )

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    description = models.TextField(blank=True)

    def __str__(self):
        return self.name

记得在settings.py中配置AUTH_USER_MODEL = 'yourapp.CustomUser'

2. 安全的余额增减操作

必须使用Django的F()表达式+数据库事务,避免并发请求下的竞态条件(这是多数人实现失败的核心原因):

# utils.py 或 views.py
from django.db import transaction
from django.db.models import F
from .models import CustomUser

def add_balance(user, amount):
    """增加用户余额"""
    with transaction.atomic():
        CustomUser.objects.filter(id=user.id).update(balance=F('balance') + amount)

def deduct_balance(user, amount):
    """扣减用户余额,返回操作是否成功"""
    with transaction.atomic():
        # 先校验余额充足,再执行扣减
        updated_rows = CustomUser.objects.filter(
            id=user.id,
            balance__gte=amount
        ).update(balance=F('balance') - amount)
        return updated_rows > 0

3. 商品购买逻辑

结合余额扣减实现完整购买流程:

# views.py
from django.shortcuts import get_object_or_404, render, redirect
from django.contrib.auth.decorators import login_required
from .models import Product
from .utils import deduct_balance

@login_required
def buy_product(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    if request.method == 'POST':
        success = deduct_balance(request.user, product.price)
        if success:
            # 可选:创建订单记录用于追溯
            # Order.objects.create(user=request.user, product=product, amount=product.price)
            return render(request, 'buy_success.html', {'product': product})
        else:
            return render(request, 'buy_fail.html', {'message': '余额不足'})
    return render(request, 'confirm_buy.html', {'product': product})

二、CharField字段修改实现

以修改CustomUser的username为例,完整实现如下:

1. 创建表单

# forms.py
from django import forms
from .models import CustomUser

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = CustomUser
        fields = ['username']  # 替换为你需要修改的CharField字段名
        widgets = {
            'username': forms.TextInput(attrs={'class': 'form-control'})
        }

2. 视图实现

类视图方式(推荐):

# views.py
from django.views.generic.edit import UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from .models import CustomUser
from .forms import UserProfileForm

class UserProfileUpdateView(LoginRequiredMixin, UpdateView):
    model = CustomUser
    form_class = UserProfileForm
    template_name = 'update_profile.html'
    success_url = reverse_lazy('profile')  # 修改成功后的跳转页面

    def get_object(self, queryset=None):
        return self.request.user  # 仅允许修改当前登录用户的字段

函数视图方式:

# views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from .forms import UserProfileForm

@login_required
def update_profile(request):
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
            return redirect('profile')
    else:
        form = UserProfileForm(instance=request.user)
    return render(request, 'update_profile.html', {'form': form})

3. 模板示例(update_profile.html)

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">保存修改</button>
</form>

常见问题排查

  • 虚拟货币操作失败:检查是否使用了F()表达式和事务,直接user.balance -= amount再user.save()会引发并发问题;
  • CharField修改失败:确保表单绑定了用户实例,视图处理了POST请求的表单验证,且目标字段在表单的fields列表中;
  • 权限问题:确认视图添加了login_required或LoginRequiredMixin,仅允许登录用户操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 10:25:23