Django自定义Clients模型登录注册功能异常求助
自定义Clients模型登录注册功能问题排查与修复
核心问题分析
你的代码存在多个不符合Django认证系统规范的问题,直接导致功能失效:
- 自定义
Clients模型未集成Django认证基类,authenticate()和login()无法识别该模型 - 注册时明文存储密码,
authenticate()无法验证加密后的密码(Django默认用PBKDF2加密) - 登录视图中已登录用户分支的
redirect('/')未加return,导致不会跳转 - 登录表单
login_client是forms.Form类型,冗余配置了仅ModelForm需要的Meta类
分步修复方案
1. 修改Clients模型(models.py)
让模型继承Django认证系统的基类,实现认证所需的字段和方法:
from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin class ClientManager(BaseUserManager): def create_user(self, email, username, first_name, last_name, password=None): if not email: raise ValueError('Users must have an email address') if not username: raise ValueError('Users must have a username') user = self.model( email=self.normalize_email(email), username=username, first_name=first_name, last_name=last_name, ) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, username, first_name, last_name, password): user = self.create_user( email, password=password, username=username, first_name=first_name, last_name=last_name, ) user.is_admin = True user.is_staff = True user.is_superuser = True user.save(using=self._db) return user class Clients(AbstractBaseUser, PermissionsMixin): created_at = models.DateField(auto_now_add=True) idClient = models.AutoField(primary_key=True) first_name = models.CharField(max_length=80) last_name = models.CharField(max_length=80) email = models.EmailField(max_length=120, unique=True) username = models.CharField(max_length=120, unique=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) is_admin = models.BooleanField(default=False) USERNAME_FIELD = 'email' # 设置登录验证用的字段 REQUIRED_FIELDS = ['username', 'first_name', 'last_name'] objects = ClientManager() def __str__(self): return self.username
2. 配置项目settings.py
添加自定义用户模型的全局配置(替换your_app_name为实际应用名称):
AUTH_USER_MODEL = 'your_app_name.Clients'
3. 优化表单与视图逻辑
forms.py:修复表单冗余配置,添加密码加密与验证
from django import forms from .models import Clients class addNewClient(forms.ModelForm): email = forms.EmailField(label="Email", widget=forms.TextInput(attrs={"class":"form-control", "placeholder":"Ex : JhonWick@gmail.com"})) first_name = forms.CharField(label="First Name ", widget= forms.TextInput(attrs={"class":"form-control", "placeholder":"Ex : Jhon"})) last_name = forms.CharField(label="Last Name", widget=forms.TextInput(attrs={"class":"form-control", "placeholder":"Ex : Wick"})) username = forms.CharField(label='Username',widget=forms.TextInput(attrs={"class":"form-control", "placeholder":"Ex : JhonWick"})) password = forms.CharField(label="Password", widget=forms.PasswordInput(attrs={"class":"form-control", "placeholder":"Ex : 32FFdl@d"})) password2 = forms.CharField(label="Confirm Password", widget=forms.PasswordInput(attrs={"class":"form-control"})) class Meta : model = Clients fields = ['username', 'first_name', 'last_name', 'email'] def clean_password2(self): password = self.cleaned_data.get('password') password2 = self.cleaned_data.get('password2') if password and password2 and password != password2: raise forms.ValidationError("Passwords don't match") return password2 def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data["password"]) if commit: user.save() return user class login_client(forms.Form): email = forms.EmailField(widget=forms.TextInput(attrs={"class":"form-control"})) password = forms.CharField(widget=forms.PasswordInput(attrs={"class":"form-control"}))
views.py:修复登录视图跳转问题,添加错误提示
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib import messages from .forms import addNewClient, login_client def login_user(request): if request.user.is_authenticated: messages.success(request, "You are Already logged in ") return redirect('/') else: if request.method == 'POST': form = login_client(request.POST) if form.is_valid(): email = form.cleaned_data['email'] password = form.cleaned_data['password'] client = authenticate(request, email=email, password=password) if client is not None: login(request, client) messages.success(request, "Login successful!") return redirect("/") else: messages.error(request, "Invalid email or password") else : form = login_client() return render(request, 'Login.html', {"form":form}) def register_user(request): if request.user.is_authenticated: messages.success(request, "You are Already logged in") return redirect("/") else : if request.method == 'POST': form = addNewClient(request.POST) if form.is_valid(): user = form.save() messages.success(request, "Registration successful! Please login.") return redirect('login') else: for field, errors in form.errors.items(): for error in errors: messages.error(request, f"{field}: {error}") else : form = addNewClient() return render(request, 'signup.html', {"form":form})
4. 执行数据库迁移
修改模型后需重新生成并执行迁移:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者lsao
相关产品推荐
相关产品推荐

