Djoser框架下使用用户名或用户名+邮箱组合实现密码重置的方法
Djoser密码重置逻辑自定义方案(支持同邮箱多用户场景)
实现步骤
- 第一步:重写默认的
ResetPasswordSerializer,替换原有仅用邮箱查询用户的逻辑,支持用户名/用户名+邮箱组合查询
from djoser.serializers import ResetPasswordSerializer from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from rest_framework import serializers User = get_user_model() class CustomResetPasswordSerializer(ResetPasswordSerializer): # 覆盖父类的必填email字段,改为非必填 email = serializers.EmailField(required=False) # 新增用户名字段,设为必填 username = serializers.CharField(required=True) def validate(self, attrs): username = attrs.get("username") email = attrs.get("email") # 构造查询条件:传了邮箱就同时匹配用户名+邮箱,否则仅匹配用户名 query_filter = {"username": username} if email: query_filter["email"] = email try: user = User.objects.get(**query_filter) except User.DoesNotExist: raise ValidationError("未找到匹配的用户信息") except User.MultipleObjectsReturned: raise ValidationError("匹配到多个用户,请补充邮箱参数确认身份") # 将匹配到的用户传入attrs,后续Djoser原生发重置邮件逻辑可直接复用 attrs["user"] = user return attrs
- 第二步:修改Django项目
settings.py中的Djoser配置,绑定自定义序列化器
DJOSER = { # 保留你原有其他Djoser配置 "SERIALIZERS": { "password_reset": "你的应用名称.serializers.CustomResetPasswordSerializer", } }
可选调整
如果业务要求仅用用户名完成密码重置,不需要邮箱参数校验,直接删掉序列化器中的email字段相关代码,validate方法仅保留用户名查询逻辑即可。
原有密码重置确认、密码修改的逻辑不需要修改,Djoser原生的uid+token校验逻辑可正常运行,和用户查询逻辑完全解耦。
内容的提问来源于stack exchange,提问作者Durgendra
相关产品推荐
相关产品推荐

