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

储蓄应用中如何在确认后提交Django客户存款表单?

解决储蓄应用存款确认表单提交失败的问题

问题描述

我正在开发一款储蓄应用,希望在显示确认表单后让用户添加客户存款。目前存款功能可正常显示确认信息,但点击确认表单上的确认按钮后,无法提交存款表单,反而跳转回存款表单,并提示amount字段不能为空。

现有代码

Model代码

class Deposit(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True)
    acct = models.CharField(max_length=6, null=True)
    staff = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    deposit_amount = models.PositiveIntegerField(null=True)
    date = models.DateTimeField(auto_now_add=True)

    def get_absolute_url(self):
        return reverse('create_account', args=[self.id])

    def __str__(self):
       return f'{self.customer} Deposited {self.deposit_amount} by {self.staff.username}'

Form代码

class CustomerDepositForm(forms.ModelForm):
    class Meta:
       model = Deposit
       fields = ['deposit_amount']

Views代码

def customer_deposit(request, id):
    context = {}
    form = CustomerDepositForm(request.POST or None)
    #Set Page Title
    page_title = "Customer Deposit"
    #Get Current Date
    current_date = datetime.now().date()
    #Get Current Month Name from Calendar
    current_month_name = calendar.month_name[date.today().month]

    try:
        #Check the Customer ID in DB
        customer = Customer.objects.get(id=id)
        #Customer Account
        acct = customer.account_number
   except Customer.DoesNotExist:
        messages.error(request, 'Customer Does Not Exist')
        return redirect('customer_create')
   else:
       #Get the Customer total deposit
       deposit = Deposit.objects.filter(customer_id = id).aggregate(total=Sum('deposit_amount')
       )['total'] or Decimal()
       if request.method == 'POST':
            #Deposit Form
            form = CustomerDepositForm(request.POST or None)
            if form.is_valid():
                amount = form.cleaned_data['deposit_amount']
                context.update(  {
                'deposit':deposit,
                'page_title':page_title,
                'customer':customer,
                'current_date':current_date,
                'current_month_name':current_month_name,
                'form':form,
                'amount':amount,
                'acct':acct,
                })
                return render(request, 'dashboard/deposit_approval_form.html', context)
            
        else:
            form = CustomerDepositForm()
            context = {
            'deposit':deposit,
            'page_title':page_title,
            'customer':customer,
            'current_date':current_date,
            'current_month_name':current_month_name,
            'form':form,
        
            'acct':acct,
            }
            return render(request, 'dashboard/deposit.html', context)

def approve_deposit(request, id):
    user = request.user
    form = CustomerDepositForm(request.POST or None)
    amount = form.cleaned_data['deposit_amount'].value()
    try:
        #Check the Customer ID in DB
        customer = Customer.objects.get(id=id)
        #Customer Account
        acct = customer.account_number
   except Customer.DoesNotExist:
       messages.error(request, 'Customer Does Not Exist')
       return redirect('customer_create')
   else:
       if request.method == 'POST':
           #Create Customer Deposit
           credit_acct = Deposit.objects.create(customer=customer, acct=acct, staff=user, deposit_amount=amount)
           credit_acct.save()
           messages.success(request, f'N{amount} Credited for Account {acct} Successfully.')
           return redirect('deposit-slip')
               
      else:
          form = CustomerDepositForm()

return render(request, 'dashboard/deposit_approval_form.html')

Deposit Approval Template代码

<form method="POST">
    {% csrf_token %} 

    <a class="btn btn-secondary" href="{% url 'create-deposit' customer.id %}">Cancel</a>
    <input class="btn btn-danger" type="submit" value="Confirm">
</form>

问题诊断

  • 确认表单未携带amount数据:当前确认表单仅包含CSRF令牌和提交按钮,未存储用户之前输入的存款金额,导致POST请求中缺失deposit_amount字段,触发表单验证错误。
  • approve_deposit视图逻辑错误:直接尝试获取form.cleaned_data['deposit_amount'].value(),未先验证表单有效性,且未处理GET请求场景,易引发异常。
  • 上下文传递未被有效利用:虽customer_deposit视图将amount传入确认页面,但模板未生成提交所需的字段。

解决方案

1. 修改确认表单模板,添加隐藏字段传递金额

在deposit_approval_form.html中添加隐藏字段存储存款金额,并指定表单提交的目标视图:

<form method="POST" action="{% url 'approve-deposit' customer.id %}">
    {% csrf_token %}
    <!-- 隐藏字段存储用户输入的存款金额 -->
    <input type="hidden" name="deposit_amount" value="{{ amount }}">
    
    <a class="btn btn-secondary" href="{% url 'create-deposit' customer.id %}">Cancel</a>
    <input class="btn btn-danger" type="submit" value="Confirm">
</form>

2. 修复approve_deposit视图逻辑

调整视图代码,先验证表单有效性,简化客户查询逻辑,处理异常情况:

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from .models import Deposit, Customer
from .forms import CustomerDepositForm

def approve_deposit(request, id):
    user = request.user
    # 直接获取客户,不存在则返回404页面
    customer = get_object_or_404(Customer, id=id)
    acct = customer.account_number

    if request.method == 'POST':
        form = CustomerDepositForm(request.POST)
        if form.is_valid():
            amount = form.cleaned_data['deposit_amount']
            # 创建存款记录
            Deposit.objects.create(
                customer=customer,
                acct=acct,
                staff=user,
                deposit_amount=amount
            )
            messages.success(request, f'N{amount} Credited for Account {acct} Successfully.')
            return redirect('deposit-slip')
        else:
            # 表单验证失败,返回存款页面提示错误
            messages.error(request, '存款金额无效,请重新输入')
            return redirect('create-deposit', id=id)
    else:
        # GET请求直接跳转到存款表单页面
        return redirect('create-deposit', id=id)

3. 优化customer_deposit视图逻辑

简化日期和月份获取方式,明确处理表单验证失败场景:

from django.utils import timezone
from django.db.models import Sum, DecimalField
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from .models import Deposit, Customer
from .forms import CustomerDepositForm

def customer_deposit(request, id):
    page_title = "Customer Deposit"
    current_date = timezone.now().date()
    current_month_name = timezone.now().strftime('%B')  # 简化月份名称获取

    customer = get_object_or_404(Customer, id=id)
    acct = customer.account_number

    # 获取客户总存款,默认值为0.00
    total_deposit = Deposit.objects.filter(customer=customer).aggregate(
        total=Sum('deposit_amount', output_field=DecimalField())
    )['total'] or Decimal('0.00')

    if request.method == 'POST':
        form = CustomerDepositForm(request.POST)
        if form.is_valid():
            amount = form.cleaned_data['deposit_amount']
            context = {
                'deposit': total_deposit,
                'page_title': page_title,
                'customer': customer,
                'current_date': current_date,
                'current_month_name': current_month_name,
                'amount': amount,
                'acct': acct,
            }
            return render(request, 'dashboard/deposit_approval_form.html', context)
        else:
            # 表单验证失败,返回带错误的存款页面
            context = {
                'deposit': total_deposit,
                'page_title': page_title,
                'customer': customer,
                'current_date': current_date,
                'current_month_name': current_month_name,
                'form': form,
                'acct': acct,
            }
            return render(request, 'dashboard/deposit.html', context)
    else:
        form = CustomerDepositForm()
        context = {
            'deposit': total_deposit,
            'page_title': page_title,
            'customer': customer,
            'current_date': current_date,
            'current_month_name': current_month_name,
            'form': form,
            'acct': acct,
        }
        return render(request, 'dashboard/deposit.html', context)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:18:15