Login,register and verify OTP API project with Django rest framework
I want to make an API project in which a person can Login, register with a phone number and OTP.
What we need to do in this project
- Login and Register from the same page.
- Verify OTP from verify image.
- When user gets register for the first time mobile number, otp, a random username,a random picture from a folder,a random profile id, a name whic is the same as mobile number gets alloted in the database.
Here's my code
modals.py
class User(models.Model):
mobile = models.CharField(max_length=20)
otp = models.CharField(max_length=6)
name = models.CharField(max_length=200)
username = models.CharField(max_length=200)
logo = models.FileField(upload_to ='profile/')
profile_id = models.CharField(max_length=200)
serializers.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['mobile']
def create(self, validated_data):
instance = self.Meta.model(**validated_data)
global totp
secret = pyotp.random_base32()
totp = pyotp.TOTP(secret, interval=300)
otp = totp.now()
instance = self.Meta.model.objects.update_or_create(**validated_data, defaults=dict(otp=str(random.randint(1000 , 9999))))[0]
instance.save()
return instance
class VerifyOTPSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['mobile','otp']
def create(self,validated_data):
instance = self.Meta.model(**validated_data)
mywords = "123456789"
res = "expert@" + str(''.join(random.choices(mywords,k = 6)))
path = os.path.join(BASE_DIR, 'static')
dir_list = os.listdir(path)
random_logo = random.choice(dir_list)
instance = self.Meta.model.objects.update_or_create(**validated_data, defaults = dict(username = res,name = instance.mobile ,logo = random_logo, profile_id = res))[0]
instance.save()
return instance
views.py
def send_otp(mobile,otp):
url = "https://www.fast2sms.com/dev/bulkV2"
authkey = settings.AUTH_KEY
querystring = {"authorization":authkey,"variables_values":otp,"route":"otp","numbers":mobile}
headers = {
'cache-control': "no-cache"
}
response = requests.request("GET", url, headers=headers, params=querystring)
print(response.text)
class RegistrationAPIView(APIView):
permission_classes = (AllowAny,)
serializer_class = ProfileSerializer
def post(self, request):
mobile = request.data['mobile']
data = User.objects.filter(mobile = mobile).first()
if data is not None:
serializer = self.serializer_class(data=request.data)
mobile = request.data['mobile']
if serializer.is_valid(raise_exception=True):
instance = serializer.save()
content = {'mobile': instance.mobile, 'otp': instance.otp}
mobile = instance.mobile
otp = instance.otp
print("Success")
send_otp(mobile,otp)
return Response(content, status=status.HTTP_201_CREATED)
else:
return Response({"Error": "Login in Failed"}, status=status.HTTP_400_BAD_REQUEST)
else:
serializer = self.serializer_class(data=request.data)
mobile = request.data['mobile']
if serializer.is_valid(raise_exception=True):
instance = serializer.save()
content = {'mobile': instance.mobile, 'otp': instance.otp}
mobile = instance.mobile
otp = instance.otp
send_otp(mobile,otp)
return Response(content, status=status.HTTP_201_CREATED)
else:
return Response({"Error": "Sign Up Failed"}, status=status.HTTP_400_BAD_REQUEST)
class VerifyOTPView(APIView):
permission_classes = (AllowAny,)
serializer_class = VerifyOTPSerializer
def post(self, request):
serializer = VerifyOTPSerializer(data=request.data)
mobile = request.data['mobile']
otp_sent = request.data['otp']
if mobile and otp_sent:
old = User.objects.filter(mobile=mobile)
if old is not None:
old = old.first()
otp = old.otp
if str(otp) == str(otp_sent):
serializer = self.serializer_class(data=request.data)
mobile = request.data['mobile']
if serializer.is_valid(raise_exception=True):
instance = serializer.save()
content = {'mobile': instance.mobile, 'otp': instance.otp, 'name':instance.name, 'username':instance.username, 'logo':instance.logo, 'profile_id': instance.profile_id }
return Response(content, status=status.HTTP_201_CREATED)
else:
return Response({
'status' : False,
'detail' : 'OTP incorrect, please try again'
})
settings.py
STATIC_URL = 'static/'
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [STATIC_DIR]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Application's urls.py
path('register/', RegistrationAPIView.as_view()),
path('verify', VerifyOTPView.as_view()),
Now, there are two problems.
- The random image is not getting saved in database i get error of not found.
- i am getting all the results i want when i register everything gets alloted fine except images but when i login with the same mobile number all the data gets updated again and i get everything new in the database. i don't want anything updated except otp.Otp should get updated everytime user login with the number but data should remain same as it was alloted at the time of registeration.