django-simple-captcha
django-simple-captcha copied to clipboard
Manually displaying the Captcha field in a template
Hi,
I'm a bit of a newbie to django-simple-captcha, but I'm finding it really useful.
I have one question, however. I've set up a django form where I've replaced the {% form.as_ul %} with the actual fields in the template. The form has django-simple-captcha hooked up but I don't know how to write the HTML code for the captcha field in my HTML template (including the dynamically generated value key).
It should be something like this:
How do I generate the dynamic value key though? Can I just create a random hex key and use that, or is there something else I can use?
thanks in advance, Mark
You don't really need to create the random code for the captcha, that's all done for you (along with validating the user input) when the form is instantiated and submitted.
You probably just need to render the captcha in your template, like so:
{{ form.captcha }}
(assuming you added a CaptchaField
to your form named captcha
)
EDIT: typo
I'm in a similar boat, I want more control than just {{captcha}}
.
What magic do I need to put in between the {{}}
below?
<div class="form-group">
<div class="col-sm-2">
{{ captcha.the_img }}
</div>
<div class="col-sm-6">
{{ captcha.the_text_box }}
{{ captcha.any_other_hidden_fields }}
</div>
</div>
<div class="col-sm-4">
{% if captcha.required %}<span class="required glyphicon glyphicon-asterisk"></span>{% endif %}
{% if captcha.help_text %}
<span class="subtle">{{ captcha.help_text|safe }}</span>
{% endif %}
{% for error in captcha.errors %}
<p class="text-danger">{{ error }}</p>
{% endfor %}
</div>
Thanks!
I know I can define the output with CAPTCHA_OUTPUT_FORMAT see http://django-simple-captcha.readthedocs.org/en/latest/advanced.html#captcha-output-format but this will set the output for the whole project. This is not flexibel enough for me. Please support more template variables as stated above.
Totally agree. I have other input fields that are written a certain way, and when I can't control the attributes that make up the captcha tags, it looks really ugly. Something like this would be nice:
<img src="{% url 'captcha-image' form.captcha.img_key %}">
{{ form.captcha.hidden_fields }}
<input type="text" name="captcha_1" some="other" attributes>
It seems that django-simple-captcha hard code the img
tag
def render(self, name, value, attrs=None):
self.fetch_captcha_store(name, value, attrs)
self.image_and_audio = '<img src="%s" alt="captcha" class="captcha" />' % self.image_url()
if settings.CAPTCHA_FLITE_PATH:
self.image_and_audio = '<a href="%s" title="%s">%s</a>' % (self.audio_url(), ugettext('Play CAPTCHA as audio file'), self.image_and_audio)
return super(CaptchaTextInput, self).render(name, self._value, attrs=attrs)
This is my solution, to control the attributes we can search the hashkey, then we can render our custom img
tag:
views.py
form = forms.RegisterForm()
captcha_hash = re.search('\w{40}', form['captcha'].__str__()).group()
return render(request, "login.html", locals())
login.html
<div class="form-group">
<div class="col-lg-offset-2 col-lg-6">
<input type="text" autocomplete="off" id="id_captcha_1" name="captcha_1" class="form-control" placeholder="validate code">
</div>
<div class="col-lg-2">
<img class="form-control" src="/user/captcha/image/{{ captcha_hash }}" />
<input id="id_captcha_0" name="captcha_0" type="hidden" value="{{ captcha_hash }}" />
</div>
</div>
@zt2 offloading the rendering of the whole field to Django's template rendering mechanism is a pretty good idea, especially because the template can be easily overridden.
I'll definitely take a look at that, my only concern is to produce a backward-compatible solution.
@zt2 your solution works for me (at least for now). Thanks!
Ok this is now implemented, you can render both the individual components (image, hidden input, text input) as well as the "assembled" elements using Django templates.
I'd really appreciate if you could check out the template-rendering
branch and give it a test before I merge it.
Edit: WIP documentation is here.
I couldn't get this to work, nor could I install 0.4.7. Even just using the default {{ captcha }} in the form template just creates an input box with no image. The docs don't discuss rendering AT ALL.
@ursomniac try this:
pip install -e git+https://github.com/mbi/django-simple-captcha.git#egg=captcha-dev
There is a link to the WIP documentation that does discuss rendering right here.
Custom widget templates introduced by Django 1.11 are enabled in #139.