我的应用程序位于Django 1.9.2和Django REST Framework 3.3.2上,前端有一个页面应用程序。我必须承认我是Django的新手,但文档是无与伦比的。
我正在尝试实现自定义PasswordResetForm视图。我的策略如下:
POST
数据(email
字符串)的前端表单上使用API端点(api/v1/password/reset
)。对于第1部分,请参阅相关代码:
# urls.py
url(r'^api/v1/password/reset/?$', PasswordResetView.as_view(), name='password-reset-link')
-
# views.py
class PasswordResetView(GenericAPIView):
serializer_class = PasswordResetSerializer
permission_classes = (AllowAny,)
def post(self, request, *args, **kwargs):
# Use DRF serializer to validate data.
serializer = self.get_serializer(data=request.data)
# Ensure data is valid before proceeding.
if serializer.is_valid() == False:
return Response('error': serializer.errors, 'message': 'Error while attempting to reset password'}, status.HTTP_400_BAD_REQUEST)
else:
# Ensure the user exists.
existing_user = get_user_model().objects.filter(
email=serializer.validated_data.get('email')
)
if not existing_user:
return Response({'error': {'code': 'email_not_in_db'}}, status.HTTP_404_NOT_FOUND)
# Validated data fed to a child class of PasswordResetForm.
form = UserForgotPasswordForm(serializer.validated_data)
if form.is_valid():
path = os.path.join(os.path.dirname(os.path.abspath(__file__ + '../../')), 'templates/registration/password_reset_email.html')
try:
# Save form, effectively attempting to trigger mail sending.
# Unfortunately an exception gets thrown!
form.save(from_email='no-reply@abc.xyz', email_template_name=path, request=request)
return Response({'message': 'Password reset request sent'}, status=status.HTTP_200_OK)
except Exception as e:
return Response({'error': str(e), 'message': 'Error while attempting to reset password'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
-
# forms.py
class UserForgotPasswordForm(PasswordResetForm):
email = forms.EmailField(required=True, max_length=254)
class Meta:
model = CustomUser
fields = ('email',)
-
# my_app/templates/registration/password_reset_email.html
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password-reset-link' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% endautoescape %}
-
但是我收到以下错误:
Reverse for 'password-reset-link' with arguments '()' and keyword arguments '{'uidb64': b'MTI1', 'token': '4g9-f370fd6ee48d90a40b67'}' not found. 1 pattern(s) tried: ['api/v1/password/reset/?$']
知道为什么吗?我错过了什么?谢谢你的帮助。
答案 0 :(得分:1)
在您的HTML中的网址中,您传递了token
和uidb64
:
{{ protocol }}://{{ domain }}{% url 'password-reset-link' uidb64=uid token=token %}
但是,在您的实际网址中,您没有引用token
或uidb64
:
url(r'^api/v1/password/reset/?$', PasswordResetView.as_view(), name='password-reset-link')
我建议您将网址更改为:
url(r'^api/v1/password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', PasswordResetView.as_view(), name='password-reset-link')
答案 1 :(得分:1)
您的名为password-reset-link
的网址不支持您发送的关键字参数uidb64
和token
。这些关键字参数不仅仅是额外的数据,它们需要匹配URL模式中的某个位置。
根据错误,您的网址格式为:
api/v1/password/reset/?$
为了支持您想要的内容,您需要将两个named arguments称为<uidb64>
和<token>
。例如:
api/v1/password/reset/(?P<uidb64>[a-zA-Z0-9]+)/(?P<token>[a-zA-Z0-9]+)/?$
您必须调整正则表达式以支持uidb64和令牌格式。