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

Django注册后无法登录问题修复请求(含自定义手机号字段)

问题分析与修复方案

你登录失败的核心原因是用户模型字段冲突、密码存储逻辑错误,以及表单与模型字段不匹配,下面是分步修复:


1. 修复用户模型(models.py)

继承AbstractUser时,它已经自带first_name、last_name、password等字段,你重复定义的字段会覆盖系统默认的密码存储逻辑,导致认证失败。同时需要设置用邮箱作为登录凭证:

from django.contrib.auth.models import AbstractUser
from django.db import models

CHARS_MAX_LENGTH = 255  # 确保这个常量已定义

class User(AbstractUser):
    # 移除重复的firstname、lastname、password,使用AbstractUser自带字段
    email = models.EmailField(max_length=CHARS_MAX_LENGTH, blank=False, unique=True)
    phone = models.CharField(max_length=20, blank=False)  # 手机号用CharField更合适

    # 设置登录时使用邮箱作为用户名
    USERNAME_FIELD = 'email'
    # 注册时必填的额外字段(除了邮箱和密码)
    REQUIRED_FIELDS = ['first_name', 'last_name', 'phone', 'username']

2. 修复注册表单(forms.py)

利用BaseUserCreationForm自带的密码验证逻辑,移除重复的密码字段,确保表单字段与模型对应:

from django.contrib.auth.forms import BaseUserCreationForm
from django import forms
from django.contrib.auth import get_user_model

User = get_user_model()

class UserCreationForm(BaseUserCreationForm):
    first_name = forms.CharField(max_length=50, required=True, label="First name")
    last_name = forms.CharField(max_length=50, required=True, label="Last name")
    email = forms.EmailField(label="Email Address")
    phone = forms.CharField(max_length=20, required=True, label="Phone number")

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'phone', 'password1', 'password2')

    def clean_email(self):
        # 单独验证邮箱是否已存在
        email = self.cleaned_data.get('email')
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError("Email already exists")
        return email

# 添加登录表单
class LoginForm(forms.Form):
    email = forms.EmailField(label="Email Address")
    password = forms.CharField(label="Password", widget=forms.PasswordInput)

3. 修复注册视图(views.py)

使用表单的save()方法创建用户,自动处理密码哈希,避免手动赋值出错:

from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from .forms import UserCreationForm, LoginForm

def register_view(request):
    """Registration view."""
    if request.method == 'GET':
        register_form = UserCreationForm()
        return render(request, 'netflix/register.html', {'register_form': register_form})
    else:
        register_form = UserCreationForm(request.POST)
        if register_form.is_valid():
            user = register_form.save(commit=False)
            user.username = user.email  # 保持用户名与邮箱一致
            user.save()
            return redirect('/login')
        return render(request, 'netflix/register.html', {'register_form': register_form})

def login_view(request):
    # Login view.
    if request.method == 'GET':
        login_form = LoginForm()
        return render(request, 'netflix/login.html', {'login_form': login_form})
    else:
        email = request.POST.get('email')
        password = request.POST.get('password')
        # 基于邮箱认证用户
        user = authenticate(request, username=email, password=password)
        if user is not None:
            login(request, user)
            return redirect('/logged_in')
        return render(
            request,
            'netflix/login.html',
            {
                'wrong_credentials': True,
                'login_form': LoginForm(request.POST)
            }
        )

4. 最后必须执行的操作

  1. 在settings.py中配置自定义用户模型:
AUTH_USER_MODEL = 'netflix.User'  # 替换成你的app名称
  1. 执行数据库迁移:
python manage.py makemigrations
python manage.py migrate

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:26:00