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

Django注册未提示用户已存在问题排查及修复请求

问题原因

你的代码中,username和email在模型里设置了unique=True,但表单层面没提前做唯一性校验,而是等到调用Account.objects.create_user()时才触发数据库的唯一约束。同时视图未捕获数据库抛出的IntegrityError异常,导致异常发生后,表单无法将错误信息传递到前端,只会重新渲染注册表单,所以看不到用户已存在的提示。

修复方案

推荐在表单类中添加字段级校验逻辑,提前在表单验证阶段检查用户名和邮箱是否已存在,错误会自动添加到表单的错误信息中,前端可直接渲染显示。

修改表单代码

在RegistrationForm类中新增clean_username和clean_email方法,同时补全clean方法的返回值:

class RegistrationForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput(attrs={
        'placeholder': 'Enter Password',
        'class': 'form-control'
    }))
    confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={
        'placeholder': 'Confirm Password',
        'class': "form-control"
    }))
    
    class Meta:
        model = Account
        fields = ['username', 'sex', 'email', 'password']
    
    def __init__(self, *args, **kwargs):
        super(RegistrationForm, self).__init__(*args, **kwargs)
        for field in self.fields:
            self.fields[field].widget.attrs['class'] = 'form-control'
            
    def clean(self):
        cleaned_data = super(RegistrationForm, self).clean()
        password = cleaned_data.get('password')
        confirm_password = cleaned_data.get('confirm_password')

        if password != confirm_password:
            raise forms.ValidationError('Password does not match!')
        return cleaned_data  # 必须返回清理后的数据,否则后续校验会丢失数据
    
    def clean_username(self):
        username = self.cleaned_data.get('username')
        if Account.objects.filter(username=username).exists():
            raise forms.ValidationError('Username already exists!')
        return username
    
    def clean_email(self):
        email = self.cleaned_data.get('email')
        if Account.objects.filter(email=email).exists():
            raise forms.ValidationError('Email already exists!')
        return email

可选:视图异常处理(不推荐)

若不想修改表单,也可在视图中捕获IntegrityError,手动将错误添加到表单:

from django.db import IntegrityError

def register(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)

        if form.is_valid():
            username = form.cleaned_data['username']
            email = form.cleaned_data['email']
            password = form.cleaned_data['password']
            sex = form.cleaned_data['sex']

            try:
                user = Account.objects.create_user(username=username, email=email, password=password, sex=sex)
                user.save()
                messages.success(request, 'Udało Ci się zarejestrować!')
                return redirect('register')
            except IntegrityError as e:
                # 根据错误信息判断是用户名还是邮箱重复
                if 'username' in str(e):
                    form.add_error('username', 'Username already exists!')
                elif 'email' in str(e):
                    form.add_error('email', 'Email already exists!')
                else:
                    form.add_error(None, 'User already exists!')
        
        context = {'form': form}
        return render(request, 'accounts/register.html', context)

    else:
        form = RegistrationForm()

    context = {'form': form}
    return render(request, 'accounts/register.html', context)

这种方式依赖数据库错误信息,可靠性和规范性不如表单层面校验,仅作备选。

前端错误渲染

确保register.html模板中正确渲染表单错误:

{% if form.errors %}
    {% for field in form %}
        {% for error in field.errors %}
            <div class="alert alert-danger">
                {{ error }}
            </div>
        {% endfor %}
    {% endfor %}
    {% for error in form.non_field_errors %}
        <div class="alert alert-danger">
            {{ error }}
        </div>
    {% endfor %}
{% endif %}

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Register</button>
</form>

内容的提问来源于stack exchange,提问作者Trollol45

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:17:08