Overriding Templates widget templates: django.template.exceptions.TemplateDoesNotExist
Zie jobsites > jobfor > widgets.py (CustomReCaptchaV3)
For others who stumble on this and are unable to set the FORM_RENDERER, I did the following which ended up working for me:
Subclass the ReCaptchaV3
and override the render method()
:
# myproject/widgets.py
from captcha.widgets import ReCaptchaV3
from django.template import loader
from django.utils.safestring import mark_safe
class CustomReCaptchaV3(ReCaptchaV3):
template_name = "recaptcha/widget_v3.html"
def render(self, name, value, attrs=None, renderer=None):
context = self.get_context(name, value, attrs)
template = loader.get_template(self.template_name) ⬅️⬅️⬅️⬅️⬅️ **Used template loader **
return mark_safe(template.render(context))
Then use Subclass the ReCaptchaField
and override the widget
and default_error_messages
:
# myproject/fields.py
from django import forms
from django.utils.translation import gettext_lazy as _
from captcha.fields import ReCaptchaField
# from captcha.widgets import ReCaptchaV3
from myproject.widgets import CustomReCaptchaV3
class ReCaptchaV3Field(ReCaptchaField):
widget = CustomReCaptchaV3 ⬅️⬅️⬅️⬅️
default_error_messages = {
"captcha_invalid": _("Fout bij het verifiëren van reCAPTCHA, probeer het opnieuw."),
"captcha_error": _("Fout bij het verifiëren van reCAPTCHA, probeer het opnieuw.")
}
Add it to your form:
## myproject/forms.py
from myproject.fields import ReCaptchaV3Field
class MyForm(forms.Form)
...
captcha = ReCaptchaField(widget=CustomReCaptchaV3, label="")
Then, assuming you have a templates directory in the root of the project, create a subdirectory called recaptcha and add your custom templates:
<!-- templates/captcha/includes/js_v3.html -->
{# The provided implementation caters for only one reCAPTCHA on a page. Override this template and its logic as needed. #}
{# Added implementation of JobAlertForm #}
<script src="https://{{ recaptcha_domain }}/recaptcha/api.js?render={{ public_key }}{% if api_params %}&{{ api_params }}{% endif %}"></script>
<script type="text/javascript">
{% if widget.name != "captcha_alert" %}
var element;
grecaptcha.ready(function() {
element = document.querySelector('.g-recaptcha[data-widget-uuid="{{ widget_uuid }}"]');
element.form.addEventListener('submit', recaptchaFormSubmit);
});
function recaptchaFormSubmit(event) {
event.preventDefault();
grecaptcha.execute('{{ public_key }}', {action: 'form'})
.then(function(token) {
console.log("reCAPTCHA validated for 'data-widget-uuid=\"{{ widget_uuid }}\"'. Setting input value...")
element.value = token;
element.form.submit();
});
}
{% else %}
{# this one is for JobAlertForm #}
grecaptcha.ready(function() {
let elm = document.querySelector('a[href="javascript:saveJobAlertIntern();"]');
elm.addEventListener('click', recaptchaSubmitAlertForm);
});
function recaptchaSubmitAlertForm(event) {
event.preventDefault();
grecaptcha.execute('{{ public_key }}', {action: 'alertForm'})
.then(function(token) {
let elm = document.querySelector('.g-recaptcha[data-widget-uuid="{{ widget_uuid }}"]');
console.log("reCAPTCHA validated for 'data-widget-uuid=\"{{ widget_uuid }}\"'. Setting input value...")
elm.value = token;
saveJobAlertIntern();
});
}
{% endif %}
</script>
Taken from comment in #183
<!-- templates/captcha/widget_v3.html -->
{% include "captcha/includes/js_v3.html" %}
<input class="g-recaptcha"
type="hidden"
name="{{ widget.name }}"
{% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}{% endfor %}
>
Comments
Post a Comment