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

Django中/crear-cliente/路径出现TypeError:int类型无len()方法

Django客户表单报错:TypeError: object of type 'int' has no len()

错误详情

TypeError at /crear-cliente/ 
object of type 'int' has no len()

错误位于C:\Users\G-FIVE\Desktop\practicas y proyectos\mini_erp\MiniErp\customers\views.py的register_customer函数第43行。

问题场景

正在开发存储客户记录的Django表单,使用类实现表单逻辑,提交时触发上述错误,以下是相关代码:

表单代码

from django import forms
from django.core import validators


# Clase para el formulario de registro de clientes
class FormCustomer(forms.Form):

    # Input para el first_name
    first_name = forms.CharField(
        label='Nombre',
        required=True,
        widget=forms.TextInput(
            attrs={
                'placeholder':'Ej: John',
                'class': 'form-control form-control-user mb-3',
                'id': 'first_name'
            }
        ),
        validators= [
            validators.MinLengthValidator(3, 'El nombre está incompleto')
        ]
    )


    # Input para el last_name
    last_name = forms.CharField(
        label='Apellido',
        required=True,
        widget=forms.TextInput(
            attrs={
                'placeholder':'Ej: Doe',
                'class': 'form-control form-control-user mb-3',
                'id': 'last_name'
            }
        ),
        validators= [
            validators.MinLengthValidator(3, 'El nombre está incompleto')
        ]
    )


    # Input para la cédula
    cedula = forms.IntegerField(
        label='Cédula',
        required=True,
        widget=forms.NumberInput(
            attrs={
                'placeholder':'xx xxx xxx',
                'class': 'form-control form-control-user mb-3',
                'id': 'cedula'
            }
        ),
        validators= [
            validators.MinLengthValidator(7, 'Faltan números'),
            validators.MaxLengthValidator(8, 'Has introducido más números')
        ]
    )


    # Input para el teléfono
    phone_number = forms.IntegerField(
        label='Teléfono',
        required=True,
        widget=forms.NumberInput(
            attrs={
                'placeholder':'04xx xxx xx xx',
                'class': 'form-control form-control-user mb-3',
                'id': 'phone_number'
            }
        ),
        validators= [
            validators.MinLengthValidator(11, 'Faltan números'),
            validators.MaxLengthValidator(11, 'Has introducido más números')
        ]
    )


    # Input para la dirección
    address = forms.CharField(
        label='Dirección',
        widget=forms.Textarea(
            attrs={
                'class': 'form-control form-control-user mb-3',
                'style': 'min-height: 150px; max-height: 150px;',
                'id': 'address'
            }
        )
    )

视图代码

# Vista que se encarga de registrar al cliente (C)
def register_customer(request):

    if request.method == 'POST':
        
        form = FormCustomer(request.POST)

        if form.is_valid():
            data_form = form.cleaned_data

            first_name = data_form['first_name']
            last_name = data_form['last_name']
            cedula = data_form['cedula']
            phone_number = data_form['phone_number']
            address = data_form['address']

            customer = Customer(
                first_name = first_name,
                last_name = last_name,
                cedula = cedula,
                phone_number = phone_number,
                address = address
            )

            customer.save()

            return redirect('home')

    elif request.method == 'GET':
        return redirect('create_customer')

模型代码

# Clase para la tabla Cliente
class Customer(models.Model):
    first_name = models.CharField(max_length=100, verbose_name='Nombre(s)')
    last_name = models.CharField(max_length=100, verbose_name='Apellido(s)')
    cedula = models.IntegerField(max_length=8, verbose_name='Cédula')
    phone_number = models.IntegerField(max_length=11, verbose_name="Teléfono")
    address = models.TextField(verbose_name='Dirección')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Creado el")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="Actualizado el")

    class Meta:
        verbose_name = 'Cliente'
        verbose_name_plural = 'Clientes'
        ordering = ['-created_at']

    def __str__(self):
        return self.first_name

解决方案

错误原因

  1. 表单层面:cedula和phone_number是IntegerField,但使用了MinLengthValidator和MaxLengthValidator——这两个验证器仅适用于字符串类型,会自动调用len()方法,但整数没有该方法,直接触发报错。
  2. 模型层面:IntegerField不支持max_length参数,该参数仅对字符串类字段有效,属于无效配置。

修复步骤

1. 修正表单字段验证

推荐将证件号、手机号改为CharField(避免丢失前导零,长度验证更适配字符串),或者使用数值范围验证器替代长度验证:

方案一:改用CharField(推荐)

# 表单中cedula字段修改为:
cedula = forms.CharField(
    label='Cédula',
    required=True,
    widget=forms.TextInput(  # 替换为TextInput,避免NumberInput自动去除前导零
        attrs={
            'placeholder':'xx xxx xxx',
            'class': 'form-control form-control-user mb-3',
            'id': 'cedula',
            'pattern': '[0-9]{7,8}',  # HTML层面限制输入数字和长度
        }
    ),
    validators= [
        validators.MinLengthValidator(7, 'Faltan números'),
        validators.MaxLengthValidator(8, 'Has introducido más números'),
        validators.RegexValidator(r'^\d+$', 'Solo se permiten números')  # 确保输入全为数字
    ]
)

# phone_number字段同理修改:
phone_number = forms.CharField(
    label='Teléfono',
    required=True,
    widget=forms.TextInput(
        attrs={
            'placeholder':'04xx xxx xx xx',
            'class': 'form-control form-control-user mb-3',
            'id': 'phone_number',
            'pattern': '[0-9]{11}',
        }
    ),
    validators= [
        validators.MinLengthValidator(11, 'Faltan números'),
        validators.MaxLengthValidator(11, 'Has introducido más números'),
        validators.RegexValidator(r'^\d+$', 'Solo se permiten números')
    ]
)

方案二:保留IntegerField,改用数值范围验证
若坚持使用整数类型,替换长度验证器为MinValueValidator和MaxValueValidator:

from django.core.validators import MinValueValidator, MaxValueValidator

# cedula字段修改:
cedula = forms.IntegerField(
    label='Cédula',
    required=True,
    widget=forms.NumberInput(
        attrs={
            'placeholder':'xx xxx xxx',
            'class': 'form-control form-control-user mb-3',
            'id': 'cedula'
        }
    ),
    validators= [
        MinValueValidator(1000000, 'Faltan números'),  # 7位最小整数
        MaxValueValidator(99999999, 'Has introducido más números')  # 8位最大整数
    ]
)

# phone_number字段同理:
phone_number = forms.IntegerField(
    label='Teléfono',
    required=True,
    widget=forms.NumberInput(
        attrs={
            'placeholder':'04xx xxx xx xx',
            'class': 'form-control form-control-user mb-3',
            'id': 'phone_number'
        }
    ),
    validators= [
        MinValueValidator(10000000000, 'Faltan números'),  # 11位最小整数
        MaxValueValidator(99999999999, 'Has introducido más números')  # 11位最大整数
    ]
)

2. 修正模型字段配置

移除IntegerField的无效max_length参数,对应表单修改方案调整模型:

对应方案一的模型修改:

# 模型中cedula和phone_number改为CharField:
cedula = models.CharField(max_length=8, verbose_name='Cédula')
phone_number = models.CharField(max_length=11, verbose_name="Teléfono")

对应方案二的模型修改:

from django.core.validators import MinValueValidator, MaxValueValidator

# 保留IntegerField,添加数值范围验证器:
cedula = models.IntegerField(
    verbose_name='Cédula',
    validators=[MinValueValidator(1000000), MaxValueValidator(99999999)]
)
phone_number = models.IntegerField(
    verbose_name="Teléfono",
    validators=[MinValueValidator(10000000000), MaxValueValidator(99999999999)]
)

3. 更新数据库

修改模型后,执行迁移命令同步数据库:

python manage.py makemigrations
python manage.py migrate

内容的提问来源于stack exchange,提问作者Angel Daniel Ascanio Salazar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:51:56