-
-
Notifications
You must be signed in to change notification settings - Fork 145
Open
Description
Hello,
I have issues implementing googles RECAPTCHA at the last form of my 3-step SessionWizardView. While testing I always get "ReCAPTCHA validation failed due to: ['timeout-or-duplicate']" in the server log, even if I click through the forms in seconds.
The captcha works with a basic view with only one form, so I assume everything with the configuration at google and with the keys is fine.
Are there known incompabilities using the captcha with the SessionWizardView?
Thanks for help
views.py
class ReservationRequestWizard(SessionWizardView):
form_list = [ReservationStep1Form, ReservationStep2Form, ReservationStep3Form]
template_name = "myapp/reservation_request_wizard.html"
def get_context_data(self, form, **kwargs):
context = super().get_context_data(form=form, **kwargs)
if self.steps.current == '1':
# ...
context['availability'] = availability
elif self.steps.current == '2':
# ...
context['total_deposit'] = total_deposit
step0_data = self.get_cleaned_data_for_step('0') or {}
context['step0_data'] = step0_data
return context
def get_form_kwargs(self, step):
kwargs = super().get_form_kwargs(step)
if step == '1':
step0_data = self.get_cleaned_data_for_step('0') or {}
# ...
kwargs['start_date'] = step0_data.get('start_date')
kwargs['end_date'] = step0_data.get('end_date')
return kwargs
def done(self, form_list, **kwargs):
step1 = form_list[0].cleaned_data
step2 = form_list[1].cleaned_data
step3 = form_list[2].cleaned_data
now = timezone.now()
reservation = Reservation.objects.create(
#...
)
# ...
return render(self.request, "myapp/reservation_request_done.html", {"reservation": reservation})
forms.py
class ReservationStep3Form(forms.Form):
request_note = forms.CharField(
widget=forms.Textarea(attrs={'rows': 4}),
required=False
)
accept_terms = forms.BooleanField(
label=mark_safe(
"I accept <a href='/static/myapp/terms.pdf' target='_blank'>Terms (PDF)</a>."
),
required=True
)
captcha = ReCaptchaField()
reservation_request_wizard.html
{% load custom_filters %}
{% block extrahead %}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<style>
.card-header {
background: #287328;
color: #fff;
}
.btn-primary {
background-color: #287328;
border-color: #287328;
}
.btn-primary:hover {
background-color: #6ECD6E;
border-color: #6ECD6E;
}
</style>
{% endblock %}
{% block content %}
<div class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<a href="{% url 'index' %}" class="btn btn-outline-secondary mb-3">
<i class="bi bi-arrow-left"></i> Back to Landing Page
</a>
<div class="card shadow">
<div class="card-header">
<h3 class="mb-0">Reservation Request</h3>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
{{ wizard.management_form }}
{% if wizard.form.non_field_errors %}
<div class="alert alert-danger">
{% for error in wizard.form.non_field_errors %}
{{ error }}<br>
{% endfor %}
</div>
{% endif %}
{% if wizard.steps.current == '0' %}
...
{% elif wizard.steps.current == '1' %}
...
{% elif wizard.steps.current == '2' %}
...
{# Step 3: Note and Terms #}
<div class="mb-3">
<label class="form-label" for="{{ wizard.form.request_note.id_for_label }}">{{ wizard.form.request_note.label|safe }}</label>
{{ wizard.form.request_note|add_class:"form-control" }}
{% if wizard.form.request_note.help_text %}
<div class="form-text">{{ wizard.form.request_note.help_text }}</div>
{% endif %}
{% for error in wizard.form.request_note.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
</div>
<div class="mb-3">
<div class="form-check">
{{ wizard.form.accept_terms }}
<label class="form-check-label" for="{{ wizard.form.accept_terms.id_for_label }}">{{ wizard.form.accept_terms.label|safe }}</label>
</div>
{% if wizard.form.accept_terms.help_text %}
<div class="form-text">{{ wizard.form.accept_terms.help_text }}</div>
{% endif %}
{% for error in wizard.form.accept_terms.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
</div>
<div class="mb-3">
{{ wizard.form.captcha }}
{% for error in wizard.form.captcha.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
<div class="d-flex justify-content-between">
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}" class="btn btn-secondary">
Back
</button>
{% endif %}
<button type="submit" class="btn btn-primary">
{% if wizard.steps.current == wizard.steps.last %}Submit{% else %}Next{% endif %}
</button>
</div>
</form>
</div>
<div class="card-footer text-muted text-end">
Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Metadata
Metadata
Assignees
Labels
No labels