Unable to render captcha for multiple forms on a single page
Closed this issue · 3 comments
I have multiple user registration forms on a single page. The captcha is getting rendered for only first form on the page and not for others. Even though I have set explicit=True
in forms.py and have also included
{% recaptcha_explicit_support %} and {% recaptcha_explicit_init %} in the template.
@kbytesys I have created a simpler template to show the issue.
{% load recaptcha2 %}
<!DOCTYPE html>
<html lang="en">
<head>
{% recaptcha_explicit_support %}
<title>Workshop</title>
</head>
<body>
{% for workshop in workshops %}
{{workshop.name}}
{{workshop.description|safe}}
{{form.as_p}}
<input type="submit">
<br>
{% endfor %}
{% recaptcha_explicit_init %}
</body>
</html>
forms.py --
class WorkshopRegistrationForm(ModelForm):
captcha = ReCaptchaField(widget=ReCaptchaWidget(explicit=True))
So the captcha never gets generated for other forms.
The problem is that it takes container id as the name of the field.
class ReCaptchaWidget(Widget):
def __init__(self, explicit=False, theme=None, type=None, size=None, tabindex=None, callback=None,
expired_callback=None, attrs={}, *args, **kwargs):
super(ReCaptchaWidget, self).__init__(*args, **kwargs)
self.explicit = explicit
self.theme = theme
self.type = type
self.size = size
self.tabindex = tabindex
self.callback = callback
self.expired_callback = expired_callback
self.attrs = attrs
def render(self, name, value, attrs=None):
template = 'snowpenguin/recaptcha/'
template += 'recaptcha_explicit.html' if self.explicit else 'recaptcha_automatic.html'
return mark_safe(
render_to_string(template, {
'container_id': 'id_%s' % name,
'public_key': settings.RECAPTCHA_PUBLIC_KEY,
'theme': self.theme,
'type': self.type,
'size': self.size,
'tabindex': self.tabindex,
'callback': self.callback,
'expired_callback': self.expired_callback
})
)
def value_from_datadict(self, data, files, name):
return [data.get('g-recaptcha-response', None)]
What if a page contains multiple forms with same field names.? The captcha will always be rendered for the first field because we are setting container id as the name of field. So if we want to render the captcha for all the fields we need to have unique ids for them. So the solution is when explicit is set true supply a unique id with the field.
So the solution is when explicit is set true supply a unique id with the field.
This could be a solution, when I will return from my holiday I will try to fix this issue.
Thanks!!!! @kbytesys