能否调用函数设置USERNAME_FIELD实现邮箱或手机号可选登录功能
可行性结论
直接通过函数动态赋值USERNAME_FIELD的方案不可行。USERNAME_FIELD是Django用户模型的固定类属性,仅支持指定单个字段作为默认身份校验字段,框架启动阶段就会完成该属性的解析和合法性校验,运行时动态修改会引发认证逻辑异常、字段校验失败等不可预期的问题。
邮箱/手机号双字段登录实现方案
不需要修改USERNAME_FIELD,通过自定义认证后端即可实现需求,步骤如下:
- 第一步:扩展用户模型,新增手机号字段(如果已有可跳过)
from django.db import models from django.contrib.auth.models import AbstractUser class CustomUser(AbstractUser): # 新增手机号字段,设置唯一约束 phone = models.CharField(max_length=11, unique=True, verbose_name="手机号")
- 第二步:编写自定义认证后端,同时匹配用户名、邮箱、手机号三个字段
from django.contrib.auth.backends import ModelBackend from django.db.models import Q from .models import CustomUser class MultiFieldAuthBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): # 入参username可传入用户名/邮箱/手机号任意一种 try: user = CustomUser.objects.get( Q(username=username) | Q(email=username) | Q(phone=username) ) except CustomUser.DoesNotExist: return None # 校验密码有效性和用户状态 if user.check_password(password) and self.user_can_authenticate(user): return user return None
- 第三步:修改项目settings.py配置,启用自定义认证后端
# 配置自定义用户模型(如果使用了扩展的CustomUser需要加) AUTH_USER_MODEL = "你的应用名.CustomUser" # 配置认证后端优先级 AUTHENTICATION_BACKENDS = [ "你的应用名.path.to.MultiFieldAuthBackend", # 保留Django默认认证后端作为兜底,可按需删除 "django.contrib.auth.backends.ModelBackend", ]
配置完成后,直接调用Django原生authenticate()方法即可实现多字段登录校验,传入的username参数可以是用户名、邮箱、手机号中的任意一种。
内容的提问来源于stack exchange,提问作者ma_as
相关产品推荐
相关产品推荐

