我正在创建一个应用,我想在其中使用自己的自定义登录表单和验证码字段。我的目的是在不使用外部库(请求除外)的情况下执行此操作,但是我无法在forms.py
的自定义表单中添加验证码字段,因此出于某种原因将其直接添加到login.html
当我执行form.is_valid()
时会返回错误。
我已经在Django - adding google recaptcha v2 to login form和Adding a Recaptcha form to my Django login page中看到了解决方案,但是正如我所说,我想不使用外部库就可以做到这一点。
views.py
...
def login_view(request):
if request.method == 'POST':
form = CustomLoginForm(request.POST)
result = is_recaptcha_valid(request)
print(result) # prints True
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Redirect to index
messages.success(request, "Logged in.")
return HttpResponseRedirect(reverse('orders:index'))
else:
messages.error(request, "Invalid credentials.")
else:
print("error")
return render(request, 'registration/login.html', {'form': CustomLoginForm()})
else:
form = CustomLoginForm()
return render(request, 'registration/login.html', {'form': form})
forms.py
class CustomLoginForm(AuthenticationForm):
email = forms.EmailField(
error_messages={
'required': 'Please enter your email.',
'invalid': 'Enter a valid email address.'
},
help_text='Email',
)
login.html
<form class="" action="{% url 'orders:login' %}" method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<!-- ReCAPTCHAV3 -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey='key-here'></div>
<button class="btn btn-success" type="submit" name="">Login</button>
<!-- <input type="hidden" name="next" value="{{ next }}"> -->
</form>
is_recaptcha_valid()
函数已经返回True
,所以我没有分享。我是Django的初学者,所以如果您能用两个词解释我做错了什么,而不仅仅是发布答案,我将不胜感激。谢谢您的宝贵时间。
答案 0 :(得分:1)
AuthenticationForm
与其他的略有不同。
如果您的支票AuthenticationForm
类,则AuthenticationForm的第一个参数不是 data ,就像其他形式一样:
class AuthenticationForm(forms.Form):
...
def __init__(self, request=None, *args, **kwargs):
...
这就是为什么您需要将 request.POST 传递给 data 。
所以像这样更新您的代码:
def login_view(request):
if request.method == 'POST':
form = CustomLoginForm(data=request.POST)
...