Reputation: 173
I'm developing a website using DjangoRest and Flutter and I want to add password reset using email.
I know that django.contrib.auth has views that help with password reset (PasswordResetView, PasswordResetDoneView, etc). But as long as I see, they return HTML files as a response when you call them in Postman.
Is there any way to use the same easy-to-use views but instead of getting HTML files, get an HTTP response so it can be called by the Flutter app?
Upvotes: 2
Views: 4924
Reputation: 2863
This can be handled in basically Two Steps:
1. One is to send anything like OTP or Reset Link view email
2. The second is to verify whether the OTP/link either is valid or not with a new password.
This can be achieved via simple function-based API views: I can demonstrate the simplest form using OTP for basic understanding, as u said you are using flutter at frontend and that will be easier to manage otp instead of link
Step 1: Add a top Field into User Model. Let's say we have field otp in the user model. Later we use it for verification purposes.
class CustomerUser(models.Model):
#...
otp = models.CharField(
max_length=6, null=True, blank=True)
# Method to Put a Random OTP in the CustomerUser table.
def save(self, *args, **kwargs):
number_list = [x for x in range(10)] # Use of list comprehension
code_items_for_otp = []
for i in range(6):
num = random.choice(number_list)
code_items_for_otp.append(num)
code_string = "".join(str(item)
for item in code_items_for_otp) # list comprehension again
# A six digit random number from the list will be saved in top field
self.otp = code_string
super().save(*args, **kwargs)
Step:2: Function to send Email with OTP on User Request
@api_view(['POST'])
def reset_request(request):
data = request.data
email = data['email']
user = CustomUser.objects.get(email=email)
if CustomUser.objects.filter(email=email).exists():
# send email with otp
send_mail(
'Subject here',
f'Here is the message with {user.otp}.',
'[email protected]',
[user.email],
fail_silently=False,
)
message = {
'detail': 'Success Message'}
return Response(message, status=status.HTTP_200_OK)
else:
message = {
'detail': 'Some Error Message'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
Last Step: Verify OTP And reset Password
@api_view(['PUT'])
def reset_password(request):
"""reset_password with email, OTP and new password"""
data = request.data
user = CustomUser.objects.get(email=data['email'])
if user.is_active:
# Check if otp is valid
if data['otp'] == user.opt:
if new_password != '':
# Change Password
user.set_password(data['password'])
user.save() # Here user otp will also be changed on save automatically
return Response('any response or you can add useful information with response as well. ')
else:
message = {
'detail': 'Password cant be empty'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
else:
message = {
'detail': 'OTP did not matched'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
else:
message = {
'detail': 'Something went wrong'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
So you can replicate it with your custom approach as well and can refactor it easily. I have used Simple API views in these examples you can check the detailed information in DRF DOCS Requests and Response Section as well
So You don't have to use HTML at all, just can work with Response, HttpResponse whatever you prefer.
Upvotes: 3