自定义User模型登录异常:提交表单提示用户已存在,无法登录
问题解决:自定义User模型登录提示「用户名已存在」
核心原因
登录表单错误使用了ModelForm,而ModelForm会自动应用模型的唯一性校验(你的MyUser模型中username字段设置了unique=True)。提交登录请求时,表单会像注册一样检查用户名是否已存在,导致出现错误提示。同时表单的clean方法存在语法错误,authenticate参数使用也不符合Django规范。
分步修正
1. 修正表单(forms.py)
将登录表单改为普通Form而非ModelForm,移除不必要的字段,修复clean方法的语法错误,仅保留登录必需的用户名和密码:
from . import models from django import forms from django.contrib.auth import authenticate class MyUserForm(forms.ModelForm): # 注册表单保持不变 class Meta(): model = models.MyUser fields = ('username','email','password','organisation') class MyUserLoginForm(forms.Form): # 登录表单改用普通Form username = forms.CharField(label="用户名") password = forms.CharField(label="密码", widget=forms.PasswordInput) def clean(self): cleaned_data = super().clean() username = cleaned_data.get('username') password = cleaned_data.get('password') if username and password: user = authenticate(username=username, password=password) if not user: raise forms.ValidationError("登录信息无效,请检查用户名和密码") return cleaned_data
2. 修正登录视图(views.py)
简化登录逻辑,无需获取email和organisation,直接从表单的cleaned_data中取用户名和密码:
from django.shortcuts import render, redirect from django.views.generic import TemplateView,CreateView from django.contrib.auth.mixins import LoginRequiredMixin from django.urls import reverse_lazy from . import models from . import forms from django.contrib.auth import authenticate,login class indexPage(TemplateView): template_name = 'accounts/inner_index.html' class Create_Organisation(CreateView): model = models.Organisation fields = ('__all__') template_name = 'accounts/organisation_form.html' success_url = reverse_lazy("accounts:inner_index") class Create_Accounts(CreateView,LoginRequiredMixin): model = models.MyUser form_class = forms.MyUserForm template_name = 'accounts/create_account.html' success_url = reverse_lazy("accounts:inner_index") def login_my_user(request): if request.method=="POST": form=forms.MyUserLoginForm(request.POST) if form.is_valid(): username = form.cleaned_data.get('username') password = form.cleaned_data.get('password') user = authenticate(username=username, password=password) if user: login(request, user) return redirect("home") else: form=forms.MyUserLoginForm() return render(request,"accounts/login_account.html",{'form':form})
3. 登录模板(login_account.html)
模板会自动适配新表单,仅显示用户名和密码字段,无需额外修改:
{% extends 'base.html' %} {% load bootstrap3 %} {% block body_block %} <form class="" method="post"> {% csrf_token %} {% bootstrap_form form %} <input type="submit" name="" value="登录"> </form> {% endblock %}
额外补充:登出功能实现
如果需要完善登出功能,可在views.py中添加:
def logout_my_user(request): logout(request) return redirect("accounts:inner_index")
并在urls.py中添加路由:
path('logout/', views.logout_my_user, name='logout'),
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

