Django注册报CustomUser对象不可下标错误及邮箱去重实现咨询
错误原因
报错回溯显示触发错误的代码是CustomUser.objects.get(email__iexact=email)[0],Django ORM的get()方法命中匹配记录时会直接返回单个CustomUser模型实例,而非可迭代的QuerySet集合,实例不支持下标[0]访问,因此触发类型错误。
你贴出的register_view代码中未包含这行逻辑,说明是你额外添加的邮箱校验代码未同步更新到贴出的片段中。
修复方法
直接删除该行末尾的[0]即可,如果你是要判断邮箱是否存在,更推荐使用filter()+exists()的写法,性能更高且不会抛出不存在的异常:
# 替换原有的get()加[0]的校验逻辑 if CustomUser.objects.filter(email__iexact=email).exists(): # 你的异常抛出逻辑
另外你当前贴出的register_view存在冗余代码:POST请求中form.is_valid()校验失败后,你重复实例化了CustomUserCreationForm(request.POST),会导致原有表单的错误信息丢失,直接删除该else分支下的这行赋值代码即可。
建议从模型层和表单层两层做校验,保证数据一致性和前端友好提示:
第一步:模型层加唯一约束(必做)
重写CustomUser模型的email字段,添加unique参数:
from django.db import models from django.contrib.auth.models import AbstractUser class CustomUser(AbstractUser): # 重写email字段添加唯一约束 email = models.EmailField(unique=True) # 原有字段保留 country = models.CharField(max_length=200, null=True, blank=True) age = models.IntegerField(default=False, null=True, blank=True) status = models.BooleanField(default=False, null=True, blank=True) def __str__(self): return self.email
修改后执行python manage.py makemigrations和python manage.py migrate生成并执行迁移,如果现有数据库中已经存在重复邮箱,需要先清理重复数据再执行迁移。
第二步:表单层加校验逻辑(用于前端友好提示)
在CustomUserCreationForm中添加clean_email钩子方法做前置校验:
from django import forms from django.contrib.auth.forms import UserCreationForm from .models import CustomUser class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser fields = ['username', 'email', 'country', 'age', 'status', 'password1', 'password2'] def clean_email(self): email = self.cleaned_data.get('email') # 忽略大小写校验邮箱是否存在 if CustomUser.objects.filter(email__iexact=email).exists(): raise forms.ValidationError("该邮箱已被注册,请更换其他邮箱") return email
加完后表单校验时会自动触发该逻辑,错误提示会直接展示在前端表单的对应字段错误区域,无需在视图中额外写校验逻辑。
内容的提问来源于stack exchange,提问作者sam hassan

