django 将参数从视图传递到表单仅一次
django pass argument from view to form only once
我有一个 OTP 生成器机制,在 GET 方法中,生成一个唯一的 4 位 OTP 并发送到 OTPAuthenticationForm(),如下所示:
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")
如何将 generated_otp 仅传递给 OTPAuthForm() 一次,以便根据用户输入的 OTP(通过电子邮件收到的 OTP)对其进行验证。
未调用 clean() 方法;而不是在执行 form.is_valid() 时,形式 return 'invalid' error
更新:OTPAuthenticationForm(forms.Form) 之前导入了 class AuthenticationForm(),它需要用户名、密码字段以及自定义 OTP场地。
这就是 form.is_valid() return 无效的原因,因为用户名、密码 auth 在应用程序中单独处理。
我认为你不应该在 GET
请求中传递 otp
,而应该由 POST
请求完成:
form = OTPAuthenticationForm(request.POST, request=request, otp=otp)
同时更新表格:
class OTPAuthenticationForm(AuthenticationForm):
otp = forms.CharField(required=True, widget=forms.TextInput)
def __init__(self, otp, *args, **kwargs):
self.otp_value = kwargs.pop("otp", None)
super(OTPAuthenticationForm, self).__init__(*args, **kwargs)
def clean(self):
otp = self.cleaned_data['otp']
if self.otp_value != otp:
raise forms.ValidationError("Invalid OTP")
return super(OTPAuthenticationForm, self).clean()
现在,问题是当您收到 POST 请求时如何存储该 OTP。你可以使用会话。像这样:
if request.method == 'GET':
otp = 'abcd'
form = OTPAuthenticationForm(request=request)
request.session['otp'] = otp # storing data in session
return ....
elif request.method == 'POST':
form = OTPAuthenticationForm(request.POST, request=request, otp=request.session.get('otp'))
if form.is_valid():
del request.session['otp'] # deleting data in session
...
我有一个 OTP 生成器机制,在 GET 方法中,生成一个唯一的 4 位 OTP 并发送到 OTPAuthenticationForm(),如下所示:
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")
如何将 generated_otp 仅传递给 OTPAuthForm() 一次,以便根据用户输入的 OTP(通过电子邮件收到的 OTP)对其进行验证。
未调用 clean() 方法;而不是在执行 form.is_valid() 时,形式 return 'invalid' error
更新:OTPAuthenticationForm(forms.Form) 之前导入了 class AuthenticationForm(),它需要用户名、密码字段以及自定义 OTP场地。
这就是 form.is_valid() return 无效的原因,因为用户名、密码 auth 在应用程序中单独处理。
我认为你不应该在 GET
请求中传递 otp
,而应该由 POST
请求完成:
form = OTPAuthenticationForm(request.POST, request=request, otp=otp)
同时更新表格:
class OTPAuthenticationForm(AuthenticationForm):
otp = forms.CharField(required=True, widget=forms.TextInput)
def __init__(self, otp, *args, **kwargs):
self.otp_value = kwargs.pop("otp", None)
super(OTPAuthenticationForm, self).__init__(*args, **kwargs)
def clean(self):
otp = self.cleaned_data['otp']
if self.otp_value != otp:
raise forms.ValidationError("Invalid OTP")
return super(OTPAuthenticationForm, self).clean()
现在,问题是当您收到 POST 请求时如何存储该 OTP。你可以使用会话。像这样:
if request.method == 'GET':
otp = 'abcd'
form = OTPAuthenticationForm(request=request)
request.session['otp'] = otp # storing data in session
return ....
elif request.method == 'POST':
form = OTPAuthenticationForm(request.POST, request=request, otp=request.session.get('otp'))
if form.is_valid():
del request.session['otp'] # deleting data in session
...