I am building an contact form with django 1.9 . My form has default inputs (fullname, email, phone, message).
To make it easier for coders forms.py:
class ContactForm(forms.Form):
full_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': _('Full Name')}),
error_messages={'required': _('Full Name is missing')}, label=_('Full Name'))
phone = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': _('Phone')}), label=_('Phone'))
email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': _('E-mail')}),
error_messages={'required': _('E-mail is missing!'), 'invalid': _('Insert a valid e-mail address!')}, label=_('E-mail'))
message = forms.CharField(widget=forms.Textarea(attrs={'rows': 9}),
error_messages={'required': _('Message is missing!')}, label=_('Messages'))
To fight against bots and spam, I've added reCAPTCHA to the template which is succesfully working.
In my view, I am first checking for POST request, then the contact form and model are defined (Model is needed for storing the contact messages to DB). As next, I validate recaptcha through grecaptcha_verify (just ignore it).
After that, the validation success check goes through
if request.POST:
contact_form = ContactForm(request.POST or None)
contact = Contact()
r = grecaptcha_verify(request)
if contact_form.is_valid() and r["success"]:
context = {
'full_name' : contact_form.cleaned_data['full_name'],
'email' : contact_form.cleaned_data['email'],
'phone' : contact_form.cleaned_data['phone'],
'message' : contact_form.cleaned_data['message'],
}
In my template, the captcha div is added within the form.
<div class="large-12 columns">
<div class="g-recaptcha" data-sitekey="6LeNhyUTAAAAAN7KdVt8FLoxlVwAYY2zPVUEy7wu"></div>
</div>
For now, everthing works fine. But I want to check if the visitor who sent the request has at least sent the g-recaptcha-response in the POST request. I could do that simply. But the problem begins here.
In forms.py, if a validation for a parameter is needed, you need to define a variable with its name and parameters (i.E. full_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': _('Full Name')}) ... ) But as it was already told, python treats hyphens as operators. So the next option that came to my mind is: why would I simply change the reCAPTCHA class name. Of course, changing it by default name 'g-recaptcha' to any other class, would not work. As I looked up in reCAPTCHA documentation, I did'nt sadly find any possibility to change the class name. So I am stuck between two specific requirements.
For now, I found a temporary solution.
In forms.py, I defined a new variable with name 'recaptcha' - which is valid.
recaptcha = forms.CharField(widget=forms.TextInput(attrs={'type': _('hidden')}), required=False)
** required is set to false
In the template, in the position where recaptcha is found, I've added error alerts for recaptcha tag:
{{ form.recaptcha }}
{% if form.errors.recaptcha %}
<div data-alert class="alert callout" data-closable="slide-out-right">
{{form.errors.recaptcha.as_text}}
<button class="close-button" aria-label="Dismiss alert" type="button" data-close>
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
In views.py, I added two if statements:
if not request.POST.get('g-recaptcha-response'):
contact_form.add_error('recaptcha','No g-captcha-response')
elif not r["success"]:
contact_form.add_error('recaptcha','Captcha verification not successfull')
This works, but is some kind of tricking django validation by injecting errors based on request.POST of the g-recaptcha-response parameter.
Is there any possibility to change the class of g-recaptcha
, so django forms can load it without hyphen issue?