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

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="&#x20B9" />
                </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实例。

修改步骤

  1. 遍历收款人数据:使用zip()配对每组name和mobile,为每组数据创建独立的payee实例。
  2. 类型转换:将POST获取的price和mobile字符串转为整数(若后续修改手机号字段为字符串则可省略mobile的转换)。
  3. 优化手机号字段:建议将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:03:15