I have an OTP generator mechanism, whereby in GET method, a unique 4-dit OTP is generated and is sent to the OTPAuthenticationForm() as follows:
views.py
if request.method == 'GET':
otp = 'abcd'
# code to send otp via mail
form = OTPAuthenticationForm(request=request, otp=otp) # this is how the OTP is passed only once.
return ....
elif request.method == 'POST':
form = OTPAuthenticationForm(request.POST, request=request)
if form.is_valid(): # the clean_field() method is not invoked/throws error.
print("OTP is valid")
else:
print("OTP is invalid")
forms.py
from django.contrib.auth.forms import AuthenticationForm
class OTPAuthenticationForm(AuthenticationForm):
otp = forms.CharField(required=True, widget=forms.TextInput)
def __init__(self, otp, *args, **kwargs):
self.otp = kwargs.pop("otp")
super(OTPAuthenticationForm, self).__init__(*args, **kwargs)
def clean(self):
if self.otp!= self.cleaned_data['otp']:
raise forms.ValidationError("Invalid OTP")
How should the generated_otp be passed only once to the OTPAuthForm() so that it could be validated against the user input OTP (OTP received via email).
The clean() method is not getting invoked; instead on execution of form.is_valid(), the form return 'invalid' error
Update: The OTPAuthenticationForm(forms.Form) was earlier importing the class AuthenticationForm() which requires the username, password fields along with the custom OTP field.
Which is why the form.is_valid() was returning as invalid since the username, password auth was being separately handled in the application.