I am currently in a fix and need your help. I am working on an API using Django_rest_framework and currently on tthe registration module. The code below is a feature that regenerate OTP and send to the current user. However, I can’t access the current user, but i have his details in the database..eg: phone_nuumber, is_active=False, is_verified=False. I want to be able to access the user using his phone number then regennerate OTP and send to his phone number after the OTP expires.
# regenerate OTP
class RegenerateOTP(APIView):
@swagger_auto_schema(
operation_summary="This endpoint is responsible for regenerating OTP if expired",
operation_description="This endpoint regenerate OTP after expiration period",
)
def post(self, request):
instance = CustomUser.objects.filter(is_active=False).first()
if int(instance.max_otp_try) == 0 and timezone.now() < instance.otp_max_out:
return Response(
"Max OTP try reached, try after an hour.",
status=status.HTTP_400_BAD_REQUEST,
)
otp = generateRandomOTP(100000, 999999)
otp_expire = timezone.now() + timedelta(minutes=10)
max_otp_try = int(instance.max_otp_try) - 1
instance.otp = otp
instance.otp_expire = otp_expire
instance.max_otp_try = max_otp_try
if max_otp_try == 0:
instance.otp_max_out = timezone.now() + datetime.timedelta(hours=1)
elif max_otp_try == -1:
instance.max_otp_try = settings.MAX_OTP_TRY
else:
instance.otp_max_out = None
instance.max_otp_try = max_otp_try
instance.save()
send_otp(instance.phone_number, otp)
return Response(
"successfully re-generated the new otp", status=status.HTTP_200_OK
)
I have tried saving the user’s phone_number when registering in session or cache so I can always get it back using in this view by doing:
phone_number = request.session.get('phone_number) and then pass it on to,
instance = CustomUser.objects.filter(phone_number=phone_number).first()
My problem noww is that I understand this is not a better way of implementing it wit scale at the back of my mind. I need a better way to solve this challenge please. Your help will be much appreciated.
2
Answers
You can set the
phone_number
field inCustomUser
as unique, and the useCustomUser.objects.get(phone_number=phone_number)
. You should set it as unique since you want to get access to a specific user through the phone number. Phone numbers shouldn’t repeat themselves anyways.That’ll be better than what you currently have.
Why did you need the current user to send the OTP? Is the opt needed for registration? if OTP is needed for registration, don’t fetch the user from DB. Just get the phone number and send the OTP to this phone number. If you need the current user to send OTP then make the phone_number field unique in the table and make db_index=True & use
CustomUser.objects.get(phone_number=phone_number)
,don’t use the filter on this because filter are much more expensive than get and also use try catch block to get the current user.