Python – How to create a Django form that displays a checkbox label to the right of the checkbox

checkboxdjangopython

When I define a Django form class similar to this:

def class MyForm(forms.Form):
    check = forms.BooleanField(required=True, label="Check this")

It expands to HTML that looks like this:

<form action="." id="form" method=POST>
<p><label for="check">Check this:</label> <input type="checkbox" name="check" id="check" /></p>
<p><input type=submit value="Submit"></p>
</form>

I would like the checkbox input element to have a label that follows the checkbox, not the other way around. Is there a way to convince Django to do that?

[Edit]

Thanks for the answer from Jonas – still, while it fixes the issue I asked about (checkbox labels are rendered to the right of the checkbox) it introduces a new problem (all widget labels are rendered to the right of their widgets…)

I'd like to avoid overriding _html_output() since it's obviously not designed for it. The design I would come up with would be to implement a field html output method in the Field classes, override the one for the Boolean field and use that method in _html_output(). Sadly, the Django developers chose to go a different way, and I would like to work within the existing framework as much as possible.

CSS sounds like a decent approach, except that I don't know enough CSS to pull this off or even to decide whether I like this approach or not. Besides, I prefer markup that still resembles the final output, at least in rendering order.

Furthermore, since it can be reasonable to have more than one style sheet for any particular markup, doing this in CSS could mean having to do it multiple times for multiple styles, which pretty much makes CSS the wrong answer.

[Edit]

Seems like I'm answering my own question below. If anyone has a better idea how to do this, don't be shy.

Best Answer

Here's a solution I've come up with (Django v1.1):

{% load myfilters %}

[...]

{% for field in form %}
    [...]
    {% if field.field.widget|is_checkbox %}
      {{ field }}{{ field.label_tag }}
    {% else %}
      {{ field.label_tag }}{{ field }}
    {% endif %}
    [...]
{% endfor %}

You'll need to create a custom template tag (in this example in a "myfilters.py" file) containing something like this:

from django import template
from django.forms.fields import CheckboxInput

register = template.Library()

@register.filter(name='is_checkbox')
def is_checkbox(value):
    return isinstance(value, CheckboxInput)

More info on custom template tags available here.

Edit: in the spirit of asker's own answer:

Advantages:

  1. No futzing with CSS.
  2. The markup ends up looking the way it's supposed to.
  3. I didn't hack Django internals. (but had to look at quite a bunch)
  4. The template is nice, compact and idiomatic.
  5. The filter code plays nice regardless of the exact values of the labels and input field names.

Disadvantages:

  1. There's probably something somewhere out there that does it better and faster.
  2. Unlikely that the client will be willing to pay for all the time spent on this just to move the label to the right...