Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
462 views
in Technique[技术] by (71.8m points)

python - How do I create a Django form that displays a checkbox label to the right of the checkbox?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...