自定义EmailBackend后无法登录Django Admin界面
Django Admin无法使用邮箱登录的解决方法
问题背景
已替换Django默认认证后端为自定义实现,支持邮箱登录,具体代码如下:
自定义认证后端(accounts/backends.py)
# 重写认证方法,使用邮箱替代用户名登录 class EmailBackend(ModelBackend): def authenticate(self, request, email = None, password = None): UserModel = get_user_model() try: user = UserModel.objects.get(email=email) except UserModel.DoesNotExist: return None if user.check_password(password): return user return None
settings.py配置
AUTH_USER_MODEL = "accounts.User" AUTHENTICATION_BACKENDS = ["accounts.backends.EmailBackend"]
自定义User模型(accounts/models.py)
class User(AbstractUser): email = models.EmailField(max_length=64, unique=True) courses = models.ManyToManyField(Course, blank=True)
当前问题
自定义前端登录表单可正常使用邮箱登录,但Django Admin界面无法登录。
已尝试操作
- 删除迁移文件夹及数据库,重新执行
makemigrations和migrate - 重启服务器
- 创建新的超级用户
解决方案
Django Admin的登录表单默认传递的是username参数,而你的自定义认证后端只接收email参数,导致Admin登录时无法匹配用户。修改认证后端的authenticate方法,兼容username参数即可:
基础修复(仅支持邮箱登录Admin)
class EmailBackend(ModelBackend): def authenticate(self, request, username=None, password=None): UserModel = get_user_model() try: # 将Admin传递的username参数当作邮箱匹配用户 user = UserModel.objects.get(email=username) except UserModel.DoesNotExist: return None if user.check_password(password): return user return None
进阶方案(同时支持用户名和邮箱登录)
如果需要同时兼容用户名和邮箱登录,可使用Q查询实现:
from django.db.models import Q class EmailBackend(ModelBackend): def authenticate(self, request, username=None, password=None): UserModel = get_user_model() try: # 同时匹配邮箱或用户名 user = UserModel.objects.get(Q(email=username) | Q(username=username)) except UserModel.DoesNotExist: return None if user.check_password(password): return user return None
修改后重启服务器,即可使用邮箱登录Django Admin界面。
内容的提问来源于stack exchange,提问作者skagamer543
相关产品推荐
相关产品推荐

