Как создать функцию восстановления пароля с помощью фреймворка Django rest?

У меня есть приложение Django Rest Framework. И я пытаюсь создать функцию сброса пароля. Но проблема заключается в том, что некоторые функции не вызываются Django Rest Framework.

Так вот, у меня есть модуль accounts--> templates --> registration и затем html шаблоны в нем. Например:

  • password_reset
  • password_reset_confirm
  • password_reseet_done
  • password_reset_form

А в модуле счетов у меня есть файл views.py:

from django.shortcuts import render
from django.utils.http import urlsafe_base64_decode
from django.utils.encoding import force_str
from django.contrib.auth.tokens import default_token_generator
from rest_framework import generics
from .serializers import ChangePasswordSerializer

class PasswordResetConfirmView(generics.GenericAPIView):
    serializer_class = ChangePasswordSerializer

    def get(self, request, uidb64, token, *args, **kwargs):
        try:
            uid = force_str(urlsafe_base64_decode(uidb64))
            user = UserModel.objects.get(pk=uid)
        except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
            user = None

        if user is not None and default_token_generator.check_token(user, token):
            return render(request, 'registration/password_reset_confirm.html', {'validlink': True, 'user': user, 'uidb64': uidb64, 'token': token})
        else:
            return render(request, 'registration/password_reset_confirm.html', {'validlink': False})

    def post(self, request, uidb64, token, *args, **kwargs):
        try:
            uid = force_str(urlsafe_base64_decode(uidb64))
            user = UserModel.objects.get(pk=uid)
        except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
            user = None

        if user is not None and default_token_generator.check_token(user, token):
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            return Response({"message": "Password has been reset successfully."}, status=status.HTTP_200_OK)
        else:
            return Response({"error": "Invalid link."}, status=status.HTTP_400_BAD_REQUEST)

И файл serializers.py:

from django.utils.translation import gettext as _
from django.contrib.auth import (get_user_model, authenticate)
from rest_framework import serializers

from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from django.contrib.auth import get_user_model
from django.template.loader import render_to_string
from rest_framework import serializers
from django.core.mail import send_mail
from django.urls import reverse
from django.conf import settings

from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.models import User
from django.utils.encoding import force_bytes, force_str
from django.utils.http import urlsafe_base64_decode
from rest_framework import serializers




UserModel = get_user_model()

class PasswordResetSerializer(serializers.Serializer):
    email = serializers.EmailField()

    def validate_email(self, value):
        if not UserModel.objects.filter(email=value).exists():
            raise serializers.ValidationError("There is no user with this email address.")
        return value

    def save(self):
        email = self.validated_data['email']
        user = UserModel.objects.get(email=email)

        # Generate token and uid
        token = default_token_generator.make_token(user)
        uid = urlsafe_base64_encode(force_bytes(user.pk))

        # Prepare email
        reset_link = self.context['request'].build_absolute_uri(
            reverse('accounts:password_reset_confirm', kwargs={'uidb64': uid, 'token': token})
        )
        subject = "Password Reset Requested"
        email_template_name = "registration/password_reset_email.html"
        context = {
            "email": user.email,
            "reset_link": reset_link,
            "user": user,
        }
        email = render_to_string(email_template_name, context)
        
        # Send email
        send_mail(subject, email, settings.DEFAULT_FROM_EMAIL, [user.email], fail_silently=False)

class PasswordResetConfirmSerializer(serializers.Serializer):
    uidb64 = serializers.CharField()
    token = serializers.CharField()
    new_password = serializers.CharField(write_only=True)
    re_new_password = serializers.CharField(write_only=True)

    def validate(self, data):
        uid = force_str(urlsafe_base64_decode(data.get('uidb64')))
        self.user = User.objects.get(pk=uid)
        if not default_token_generator.check_token(self.user, data.get('token')):
            raise serializers.ValidationError("The reset link is invalid or has expired")
        if data.get('new_password') != data.get('re_new_password'):
            raise serializers.ValidationError("The two password fields didn't match.")
        return data

    def save(self):
        self.user.set_password(self.validated_data['new_password'])
        self.user.save()

А мой основной файл urls.py выглядит так:

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
from drf_spectacular.views import (SpectacularAPIView, SpectacularSwaggerView)

from rest_framework.schemas import get_schema_view

urlpatterns = [
   
    path('admin/', admin.site.urls),
    path('api/', include('DierenWelzijnAdmin.urls')),
    path('api-auth/', include('rest_framework.urls')),
    path('schema/', get_schema_view()),
    path('api/schema/', SpectacularAPIView.as_view(), name='api-schema'),
    path('api/docs', SpectacularSwaggerView.as_view(url_name='api-schema'),
         name='api-docs'),
     path('accounts/', include(('accounts.urls','accounts'), namespace='accounts'))    

А urls.py в модуле accounts выглядит так:

from django.urls import path
from rest_framework.authtoken.views import obtain_auth_token
from accounts import views
from .views import( ChangePasswordView,  PasswordResetView,
    PasswordResetConfirmView, send_test_email )

app_name='accounts'

urlpatterns = [
    
    path('password-reset/', PasswordResetView.as_view(), name='password-reset'),      
    path('password-reset-confirm/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('send-test-email/', send_test_email, name='send_test_email'),

И я пытаюсь вызвать api вызов password-reset с url:

http://127.0.0.1:8000/accounts/password-reset/

Но каждый раз я получаю эту ошибку:

NoReverseMatch в /accounts/password-reset/ Reverse for 'password_reset_confirm' не найден. 'password_reset_confirm' не является не является действительной функцией представления или именем шаблона. Метод запроса: POST-запрос URL: http://127.0.0.1:8000/accounts/password-reset/ Django Версия: 5.0.6 Тип исключения: NoReverseMatch Значение исключения: Не найден реверс для 'password_reset_confirm'. 'password_reset_confirm' не является действительной функцией представления или именем шаблона.

Вопрос: как вызвать api вызов: password-reset без ошибки?

Вернуться на верх