10

I've created a custom template for rendering form fields:

<tr class="{{field.field.widget.attrs.class}}">
    <th class="label">
        <label for="{{field.auto_id}}">
            {{field.label}}
            {% if not field.field.required %}<span class="optional">(optional)</span>{% endif %}
        </label>
    </th>
    <td class="field">
        {{field}}
        {% if field.errors %}<label class="error" for="{{field.auto_id}}">{{field.errors.0}}</label>{% endif %}
        {% if field.help_text %}<small class="help-text">{{field.help_text}}</small>{% endif %}
    </td>
</tr>

But I want to check if the widget is a checkbox, and if so, render it differently. How can I do that in the template?

5
  • Hi - is there a particular reason why you need to do it in the template, rather than setting a custom widget in the form class? Commented Oct 13, 2010 at 19:03
  • 1
    @stevejalim: I can create a custom widget, but it doesn't solve the issue. I want to set colspan=2 and have the label on the right side. This is an issue with how the table row is laid out, not with how the widget is rendered. Commented Oct 13, 2010 at 19:05
  • gotcha. One (hacky) way to do it is to pass in a list of fields known to be checkboxes and each time you render the field, check if it's name is in that list, and if so, set your colspan there. Icky, though ;o) Commented Oct 13, 2010 at 20:00
  • Very icky. I'm trying to clean up all that ick right now, not add more to it :) Commented Oct 13, 2010 at 20:10
  • Similar question: stackoverflow.com/questions/1809874/… Commented Aug 12, 2016 at 13:42

3 Answers 3

20

Use a custom template filter!

In yourapp/templatetags/my_custom_tags.py:

from django import template
from django.forms import CheckboxInput

register = template.Library()

@register.filter(name='is_checkbox')
def is_checkbox(field):
  return field.field.widget.__class__.__name__ == CheckboxInput().__class__.__name__

In your template:

{% load my_custom_tags %}
 
{% if field|is_checkbox %}
  do something
{% endif %}

Side note on implementation: when I don't instantiate a CheckboxInput, the class name is MediaDefiningClass.

>>> form django.forms import CheckboxInput
KeyboardInterrupt
>>> CheckboxInput.__class__.__name__
'MediaDefiningClass'
Sign up to request clarification or add additional context in comments.

2 Comments

And today there's a special Django utility application which has similar checker and other stuff: pypi.python.org/pypi/django-form-utils#is-checkbox
I'd say that it's cleaner to use something like this: return isinstance(field.field.widget, CheckboxInput).
12

{{ field.field.widget.input_type }} will get you this info for a lot of widgets, but not all. I'm not sure if it'll work for the default checkbox widget or not. Worth a shot.

1 Comment

Don't think CheckboxInput has this attribute... it does however appear to have a check_test attribute... I don't know if it's unique to the checkbox input...but it's working for now... bit of a hack though.
7

It is kind of late to answer, but I implemented something similar to what is done in Django's admin.

First, I added a new attribute is_checkbox to the Field class:

# forms.py
from django import forms
from django.forms.fields import Field
setattr(Field, 'is_checkbox', lambda self: isinstance(self.widget, forms.CheckboxInput ))

Then, I can easily detect a CheckboxInput widget in the template. Here is an example to render checkboxes to the left and other widgets to the right:

{% if field.field.is_checkbox %}
    {{ field }} {{ field.label_tag }}
{% else %}
    {{ field.label }} {{ field }}
{% endif %}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.