Search code examples
python-3.xdjangodjango-rest-frameworkdjango-viewsdjango-serializer

Forgot Password API Django rest framework


I am using OTP authentication for the Forgot password of user. I want the phone no get verify then the user can able to change the password of their account.

I want to change the password of the user if the user can verify their number the new password could get set.

I someone able to give an answer please help.

serializers.py

class PasswordSerializer(serializers.Serializer):
    """
    Serializer for password change endpoint.
    """

    new_password = serializers.CharField(required=True)

models.py

class ResetPhoneOTP(models.Model):

    phone_regex = RegexValidator( regex = r'^\+?1?\d{9,14}$', message = "Phone number must be entered in the form of +919999999999.")
    phone = models.CharField(validators = [phone_regex], max_length=17, blank=True)
    otp = models.CharField(max_length=9, blank=True, null=True)
    count = models.IntegerField(default=0, help_text = 'Number of opt_sent')
    validated = models.BooleanField(default=False, help_text= 'if it is true, that means user have validate opt correctly in seconds')


    def __str__(self):
        return str(self.phone) + ' is sent ' + str(self.otp)

views.py

            
            
class UserViewSet(mixins.ListModelMixin,
                  mixins.RetrieveModelMixin,
                  mixins.UpdateModelMixin,
                  viewsets.GenericViewSet):
    """
    list:
    Return a list of all the existing users.
    read:
    Return the given user.
    me:
    Return authenticated user.
    """
    queryset = User.objects.all()
    serializer_class = PasswordSerializer
    # permission_classes = (IsSuperuserOrIsSelf,)


    # @action(detail=True, methods=['put'])
    def post(self, request):
        phone = request.data.get('phone' , False)
        # new_password = request.data.get('new_password')
        if phone:
            old = ResetPhoneOTP.objects.filter(phone__iexact = phone)
            if old.exists():
                old  = old.last()
                validated = old.validated

                if validated:

                    serializer = PasswordSerializer(data=request.data)

                    if serializer.is_valid():
                        user.set_password(serializer.data.get('new_password'))
                        user.save()
                        return Response({'status': 'password set'}, status=status.HTTP_200_OK)
                    return Response({'status': 'password not2 set'})
                return Response({'status': 'password not3 set'})
        return Response({'status': 'password not 4set'})   

class ResetPassword(APIView):
    permission_classes = (AllowAny, )
    def post(self, request, *args, **kwargs):
        phone_number = request.data.get('phone' )
        if phone_number :
            phone  = str(phone_number)
            key = send_reset_otp(phone)
            old = User.objects.filter(phone=phone)
            if old.exists():
                # old  = old.first()
                # count = old.count
                # old.count = count + 1
                # old.save()
                ResetPhoneOTP.objects.create(
                    # name = name,
                    phone = phone,
                    otp = key

                    )
                # print('Count Increase', count)
              
                # print(key)
                return Response({
                        'status' : True,
                        'detail' : 'OTP sent successfully.'
                        })
            else:
                return Response({
                    'status' : False,
                    'detail' : 'Phone Number DoesNotExist'
                })
        else:
            return Response({
                'status' : False,
                'detail' : 'Phone Number is not given in body.'
            })

class ValidateResetOTP(APIView):
    permission_classes = (AllowAny, )
    def post(self, request, *args, **kwargs):
        phone = request.data.get('phone' , False)
        otp_sent = request.data.get('otp', False)

        if phone and otp_sent:
            old = ResetPhoneOTP.objects.filter(phone__iexact = phone)
            if old.exists():
                old = old.last()
                otp = old.otp
                # old = Customer.objects.filter(otp)
                if str(otp_sent) == str(otp):
                    old.validated = True
                    old.save()
                    return Response({
                        'status' : True,
                        'detail' : 'OTP mactched. Please proceed for Reset Password.'
                        })
                else: 
                    return Response({
                        'status' : False,
                        'detail' : 'OTP incorrect.'
                        })
            else:
                return Response({
                    'status' : False,
                    'detail' : 'First proceed via sending otp request.'
                    })
        else:
            return Response({
                'status' : False,
                'detail' : 'Please provide both phone and otp for validations'
                })

Solution

  •  ​from​ ​django​.​contrib​.​auth​.​hashers​ ​import​ ​make_password
     
     ​#Your api view
     ​    ​username​ ​=​ ​request​.​user 
     ​    ​get_obj​ ​=​ ​User​.​objects​.​get​(​id​=​request​.​user​.​id​) 
     ​    ​if​ (​request​.​method​ ​==​ ​'POST'​): 
     ​        ​password​ ​=​ ​request​.​data​.​get​(​'password'​) ​#Get pass value from form 
     ​        ​password1​ ​=​ ​request​.​POST​.​get​(​'password1'​) ​#Get password1 value from form 
     ​        ​if​ ​password​ ​==​ ​password1​: 
     ​            ​user​ ​=​ ​User​.​objects​.​get​(​username​=​request​.​user​) 
     ​            ​pas​ ​=​ ​make_password​(​password​) 
     ​            ​user​.​password​ ​=​ ​pas 
     ​            ​user​.​save​() 
     ​            ​return Response (' success')