Django表单提交报错:Field 'mobile'期望数字却接收到数组
解决Django动态表单提交的TypeError问题
问题场景
使用Django 4.1开发表单提交功能时,通过JavaScript动态生成多组包含name和mobile的收款人输入框,提交后出现TypeError,提示**"Field 'mobile' expected a number but got ['22222', '3333']"**,无法将多组收款人信息存入payee模型。
错误信息
TypeError at /page Field 'mobile' expected a number but got ['22222', '3333']. Request Method: POST Request URL: http://127.0.0.1:8000/page Django Version: 4.1 Exception Type: TypeError Exception Value: Field 'mobile' expected a number but got ['22222', '3333'].
相关代码
Views.py
def page(request): if request.method == 'POST': description = request.POST['description'] price = request.POST['price'] name = request.POST.getlist('name') mobile = request.POST.getlist('mobile') pay = bill(description=description,price=price) pay.save() mypayee = payee(billId=pay,name=name,mobile=mobile) mypayee.save() return render(request, 'split_app/page.html')
模型代码
from django.db import models # Create your models here. class bill(models.Model): price = models.IntegerField() description = models.CharField(max_length=200) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.description class payee(models.Model): billId = models.ForeignKey(bill,on_delete=models.CASCADE,related_name='persons') name = models.CharField(max_length=50) mobile = models.IntegerField()
HTML代码
<div class="container my-3"> <button type="button" class="btn btn-secondary">ADD NEW BILL</button> <form action="/page" method="POST"> {% csrf_token %} <div class="input-group mb-3"> <label for="discription" class="col-sm-2 col-form-label">DESCRIPTION:</label> <div class="col-sm-2"> <input type="text" name="description" id="discription" placeholder="Bill For.." /> </div> </div> <div class="input-group mb-3"> <label for="price" class="col-sm-2 col-form-label">BILL PRICE:</label> <div class="col-sm-2"> <input type="number" name="price" id="price" title="only numbers allowed" placeholder="₹" /> </div> </div> <div class="mb-3 row"> <label for="person" class="col-sm-2 col-form-label">SPLIT IN:</label> <div class="col-sm-10"> <button type="button" class="btn btn-info" onclick="increment()">+</button> <button type="button" class="btn btn-info" id="payeesbtn">ADD PAYEE:</button> <button type="button" class="btn btn-info" onclick="decrement()">-</button> <div class="container my-3" id="addpayees"></div> </div> </div> <button type="submit" class="btn btn-info">Save</button> </form> </div>
JavaScript代码
let x = 1; function increment() { const div = document.createElement('div'); div.className = 'container my-3'; div.idName = 'x'; div.innerHTML = `<h5>payee ${x}</h5> <table> <tr> <th>Name:</th> <td><input type="text" name="name"></td> </tr> <tr> <th>Mobile:</th> <td><input type="number" name="mobile"></td> </tr> </table> <input type="button" value="-" onclick="decrement(this)" /> <button type="button" class="btn btn-info" onclick="decrement(this)">-</button>`; document.getElementById("addpayees").appendChild(div); x++; };
解决方案
错误原因
视图中通过getlist()拿到的name和mobile是数组,但payee模型的name和mobile都是单个字段,直接将数组传入模型实例会导致类型不匹配;同时未对每组收款人信息单独创建payee实例。
修改步骤
- 遍历收款人数据:使用
zip()配对每组name和mobile,为每组数据创建独立的payee实例。 - 类型转换:将POST获取的
price和mobile字符串转为整数(若后续修改手机号字段为字符串则可省略mobile的转换)。 - 优化手机号字段:建议将
payee模型的mobile字段从IntegerField改为CharField,避免手机号前导零丢失或超长问题。
修改后的代码
更新后的Views.py
def page(request): if request.method == 'POST': description = request.POST['description'] # 将price字符串转为整数 price = int(request.POST['price']) names = request.POST.getlist('name') mobiles = request.POST.getlist('mobile') pay = bill(description=description, price=price) pay.save() # 遍历每组收款人信息,创建对应的payee实例 for name, mobile_str in zip(names, mobiles): mobile = int(mobile_str) mypayee = payee(billId=pay, name=name, mobile=mobile) mypayee.save() return render(request, 'split_app/page.html')
优化后的模型代码(可选但推荐)
class payee(models.Model): billId = models.ForeignKey(bill, on_delete=models.CASCADE, related_name='persons') name = models.CharField(max_length=50) # 改为CharField存储手机号,适配带前导零或特殊格式的号码 mobile = models.CharField(max_length=15)
说明
JavaScript动态生成的输入框无需修改,name属性设置为name和mobile可让getlist()正确获取所有输入值的数组。
内容的提问来源于stack exchange,提问作者Shamshad z
相关产品推荐
相关产品推荐

