Django与Stripe集成:支付表单提交时full_name字段未填充问题
解决Django+Stripe支付表单中客户姓名无法存入数据库的问题
问题概述
提交支付表单后,客户姓名无法存入Order模型的full_name字段,抛出错误:
django.db.utils.IntegrityError: NOT NULL constraint failed: orders_order.full_name
错误原因排查
- 后端未正确接收前端参数:前端通过AJAX发送
custName参数,但可能存在参数传递失败、键名不匹配或值为空的情况。 - 模型必填字段未完全填充:
Order模型中除full_name外,city、phone、post_code等字段也是必填项,当前代码未传入这些值,后续会触发更多约束错误。 - 前端表单缺失必要控件:模板中未包含
phone、city等必填字段的输入框,无法收集对应数据。
解决方案
1. 调试后端参数接收
在add视图中添加调试代码,确认是否接收到custName的值:
def add(request): basket = Basket(request) if request.POST.get('action') == 'post': order_key = request.POST.get('order_key') cust_name = request.POST.get('custName') # 打印接收的客户姓名,确认是否传值成功 print("Received cust_name:", cust_name) # 校验客户姓名是否为空 if not cust_name: return JsonResponse({'error': '客户姓名不能为空'}, status=400) # 后续代码...
2. 完善前端AJAX请求参数
确保前端传递所有必要字段到后端:
form.addEventListener('submit', function(ev) { ev.preventDefault(); var custName = document.getElementById("custName").value; var custAdd = document.getElementById("custAdd").value; var custAdd2 = document.getElementById("custAdd2").value; var postCode = document.getElementById("postCode").value; // 获取新增的电话、城市输入值(需先在模板添加对应控件) var phone = document.getElementById("phone").value; var city = document.getElementById("city").value; $.ajax({ type: "POST", url: 'http://127.0.0.1:8000/orders/add/', data: { order_key: clientsecret, csrfmiddlewaretoken: CSRF_TOKEN, action: "post", custName: custName, postCode: postCode, phone: phone, city: city, address1: custAdd, address2: custAdd2 }, success: function (json) { console.log(json.success) // 后续Stripe支付逻辑... }, error: function (xhr, errmsg, err) {}, }); });
3. 补充模板表单控件
添加缺失的phone和city输入框到表单中:
<div class="col-12"> <label for="city" class="form-label">City</label> <input type="text" class="form-control" id="city" placeholder="Your city" required> <div class="invalid-feedback"> City is required. </div> </div> <div class="col-12"> <label for="phone" class="form-label">Phone Number</label> <input type="text" class="form-control" id="phone" placeholder="Your phone number" required> <div class="invalid-feedback"> Phone number is required. </div> </div>
4. 修复后端订单创建逻辑
确保创建Order实例时传入所有必填字段:
def add(request): basket = Basket(request) if request.POST.get('action') == 'post': order_key = request.POST.get('order_key') cust_name = request.POST.get('custName') post_code = request.POST.get('postCode') phone = request.POST.get('phone') city = request.POST.get('city') address1 = request.POST.get('address1') address2 = request.POST.get('address2') # 校验所有必填字段是否齐全 required_fields = [cust_name, post_code, phone, city, address1] if not all(required_fields): return JsonResponse({'error': '请填写所有必填字段'}, status=400) user_id = request.user.id baskettotal = basket.get_total_price() if Order.objects.filter(order_key=order_key).exists(): return JsonResponse({'success': '订单已存在'}) else: order = Order.objects.create( user_id=user_id, full_name=cust_name, address1=address1, address2=address2, city=city, phone=phone, post_code=post_code, total_paid=baskettotal, order_key=order_key ) order_id = order.pk for item in basket: OrderItem.objects.create( order_id=order_id, product=item['product'], price=item['price'], quantity=item['qty'] ) return JsonResponse({'success': '订单创建成功'})
5. 可选:优化模型字段(非必须)
如果部分字段允许为空,可修改模型字段添加blank=True或null=True:
class Order(models.Model): # ...其他字段 city = models.CharField(max_length=100, blank=True, null=True) phone = models.CharField(max_length=100, blank=True, null=True) # ...其他字段
验证步骤
- 启动Django服务,打开支付页面。
- 填写所有表单字段,点击支付按钮。
- 检查数据库
orders_order表的full_name及其他字段是否正确填充。 - 查看浏览器开发者工具的Network标签,确认AJAX请求的Form Data包含所有参数。
内容的提问来源于stack exchange,提问作者Rey1245
相关产品推荐
相关产品推荐

