有人可以建议如何实现自定义 Django PasswordResetView 吗?
Can someone suggest how to implement custom Django PasswordResetView?
我只想将密码重置 link 发送到已确认的电子邮件地址。并且用户还可以通过搜索用户名或电子邮件地址来请求重置密码 link,这在默认的 django 中是不可用的。很多天来,我一直在尝试和编辑默认的 django 密码重置视图和表单。但不为我工作。
您可以从 扩展 PasswordResetView
rest_auth.views
并在其中做更多的逻辑
例如
from rest_auth.views import PasswordChangeView, PasswordResetView, PasswordResetConfirmView
sensitive_post_parameters_m = method_decorator(
sensitive_post_parameters(
'password', 'old_password', 'new_password1', 'new_password2'
)
)
class PasswordResetViewNew(PasswordResetView):
def post(self, request, *args, **kwargs):
email = request.data.get('email')
try:
if User.objects.get(email=email).active:
return super(PasswordResetViewNew, self).post(request, *args, **kwargs)
except:
# this for if the email is not in the db of the system
return super(PasswordResetViewNew, self).post(request, *args, **kwargs)
在网址中
path('password/reset/', PasswordResetViewNew.as_view()),
编辑以回答 "How to search by username for sending password reset link"
PasswordResetView 的默认序列化程序包含
email = serializers.EmailField()
这意味着终点将不接受除电子邮件以外的任何东西
所以我们会做一些技巧让它接受字符,这样我们就可以向它发送用户名
首先我们会扩展
来自 rest_auth.serializers 的 PasswordResetSerializer
并做一些维护
from rest_auth.serializers import PasswordResetSerializer
from django.conf import settings
from django.contrib.auth.forms import PasswordResetForm
class TestSerializer(PasswordResetSerializer):
email = serializers.CharField()
# here changed the email to accept any chars
reset_form = PasswordResetForm()
def validate_email(self, value):
#here we will trick it be make email really have the email of the username entered
mutable = self.initial_data
self.initial_data._mutable = True
self.initial_data['email'] = User.objects.get(username=self.initial_data.get('email'))
# don't forget to handle exception for username that not in db
self.initial_data._mutable = mutable
return super(TestSerializer, self).validate_email(value)
我们的观点有点像这样
from django.utils.translation import gettext_lazy as _
#don't forget to import PasswordResetView, TestSerializer
class PasswordResetViewNew(PasswordResetView):
serializer_class = TestSerializer
# here we changed the default serializer to our new serializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.data['email'] = User.objects.get(username=serializer.data.get('email'))
# here we trick it again and change the email with the email for the username entered
serializer.save()
# Return the success message with OK HTTP status
return Response(
{"detail": _("Password reset e-mail has been sent.")},
status=status.HTTP_200_OK
)
我只想将密码重置 link 发送到已确认的电子邮件地址。并且用户还可以通过搜索用户名或电子邮件地址来请求重置密码 link,这在默认的 django 中是不可用的。很多天来,我一直在尝试和编辑默认的 django 密码重置视图和表单。但不为我工作。
您可以从 扩展 PasswordResetView rest_auth.views 并在其中做更多的逻辑 例如
from rest_auth.views import PasswordChangeView, PasswordResetView, PasswordResetConfirmView
sensitive_post_parameters_m = method_decorator(
sensitive_post_parameters(
'password', 'old_password', 'new_password1', 'new_password2'
)
)
class PasswordResetViewNew(PasswordResetView):
def post(self, request, *args, **kwargs):
email = request.data.get('email')
try:
if User.objects.get(email=email).active:
return super(PasswordResetViewNew, self).post(request, *args, **kwargs)
except:
# this for if the email is not in the db of the system
return super(PasswordResetViewNew, self).post(request, *args, **kwargs)
在网址中
path('password/reset/', PasswordResetViewNew.as_view()),
编辑以回答 "How to search by username for sending password reset link"
PasswordResetView 的默认序列化程序包含
email = serializers.EmailField()
这意味着终点将不接受除电子邮件以外的任何东西 所以我们会做一些技巧让它接受字符,这样我们就可以向它发送用户名
首先我们会扩展 来自 rest_auth.serializers 的 PasswordResetSerializer 并做一些维护
from rest_auth.serializers import PasswordResetSerializer
from django.conf import settings
from django.contrib.auth.forms import PasswordResetForm
class TestSerializer(PasswordResetSerializer):
email = serializers.CharField()
# here changed the email to accept any chars
reset_form = PasswordResetForm()
def validate_email(self, value):
#here we will trick it be make email really have the email of the username entered
mutable = self.initial_data
self.initial_data._mutable = True
self.initial_data['email'] = User.objects.get(username=self.initial_data.get('email'))
# don't forget to handle exception for username that not in db
self.initial_data._mutable = mutable
return super(TestSerializer, self).validate_email(value)
我们的观点有点像这样
from django.utils.translation import gettext_lazy as _
#don't forget to import PasswordResetView, TestSerializer
class PasswordResetViewNew(PasswordResetView):
serializer_class = TestSerializer
# here we changed the default serializer to our new serializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.data['email'] = User.objects.get(username=serializer.data.get('email'))
# here we trick it again and change the email with the email for the username entered
serializer.save()
# Return the success message with OK HTTP status
return Response(
{"detail": _("Password reset e-mail has been sent.")},
status=status.HTTP_200_OK
)