如何在Django自定义用户模型中实现邮箱或用户名登录功能
Django实现用户名/邮箱均可登录的修改方案
1. 调整自定义认证后端代码
修改你的backends.py文件如下:
from django.contrib.auth import get_user_model from django.contrib.auth.backends import ModelBackend class CaseInsensitiveModelBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): UserModel = get_user_model() if username is None: username = kwargs.get(UserModel.USERNAME_FIELD) user = None try: # 优先按用户名不区分大小写查询 case_insensitive_username_field = '{}__iexact'.format(UserModel.USERNAME_FIELD) user = UserModel._default_manager.get(**{case_insensitive_username_field: username}) except UserModel.DoesNotExist: # 用户名不存在时按邮箱不区分大小写查询 try: user = UserModel._default_manager.get(email__iexact=username) except UserModel.DoesNotExist: # 均不存在时执行密码哈希,避免计时攻击 UserModel().set_password(password) return None # 校验密码和用户状态 if user and user.check_password(password) and self.user_can_authenticate(user): return user return None
修改说明:
- 新增了邮箱查询分支,用户名匹配失败后自动尝试用传入的账号值匹配邮箱字段
- 补全了查询全失败后的返回逻辑,避免无返回值的异常
- 保留了原有大小写不敏感的匹配逻辑,符合通用登录体验
2. 项目配置更新
在settings.py中添加如下配置,指定使用自定义的认证后端:
AUTHENTICATION_BACKENDS = [ # 替换为你实际的app名称,比如backends.py放在userapp下就写userapp.backends.CaseInsensitiveModelBackend 'your_app_name.backends.CaseInsensitiveModelBackend' ]
注意事项
- 请确保你的自定义用户模型中
email字段设置了unique=True,避免同一邮箱对应多个账号导致查询报错 - 前端登录表单的账号输入字段名称保持
username即可,无需额外新增字段,后端会自动识别输入内容是用户名还是邮箱
内容的提问来源于stack exchange,提问作者Saud Zubedi
相关产品推荐
相关产品推荐

