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
解决方案
错误原因
- 表单层面:
cedula和phone_number是IntegerField,但使用了MinLengthValidator和MaxLengthValidator——这两个验证器仅适用于字符串类型,会自动调用len()方法,但整数没有该方法,直接触发报错。 - 模型层面:
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
相关产品推荐
相关产品推荐

