开发者

How to get a template tag to auto-check a checkbox in Django

I'm using a ModelForm class to generate a bunch of checkboxes for a ManyToManyField but I've run into one problem: while the default behaviour automatically checks the appropriate boxes (when I'm editing an object), I can't figure out how to get that information in my own custom templatetag.

Here's what I've got in my model:

from myproject.interests.models import Interest


class Node(models.Model):
    interests   = models.ManyToManyField(Interest, blank=True, null=True)


class MyForm(ModelForm):

    from django.forms import CheckboxSelectMultiple, ModelMultipleChoiceField

    interests = ModelMultipleChoiceField(
        widget=CheckboxSelectMultiple(), 
        queryset=Interest.objects.all(),
        required=False
    )

    class Meta:
        model = MyModel

And in my view:

from myproject.myapp.models import MyModel,MyForm

obj = MyModel.objects.get(pk=1)
f   = MyForm(instance=obj)

return render_to_response(
    "path/to/form.html", {
        "form": f,
    },
    context_instance=RequestContext(request)
)

And in my template:

{{ form.interests|alignboxes:"CheckOption" }}

And here's my templatetag:

@register.filter
def alignboxes(boxes, cls):
    """
        Details on how this works can be found here:
            http://docs.djangoproject.com/en/1.1/howto/custom-template-tags/
    """

    r = ""
    i = 0
    for box in boxes.field.choices.queryset:
        r += "<label for=\"id_%s_%d\" class=\"%s\">开发者_如何学C;<input type=\"checkbox\" name=\"%s\" value=\"%s\" id=\"id_%s_%d\" /> %s</label>\n" % (
            boxes.name,
            i,
            cls,
            boxes.name,
            box.id,
            boxes.name,
            i,
            box.name
        )
        i = i + 1

    return mark_safe(r)

The thing is, I'm only doing this so I can wrap some simpler markup around these boxes, so if someone knows how to make that happen in an easier way, I'm all ears. I'd be happy with knowing a way to access whether or not a box should be checked though.


In your input tag for the checkbox, you can just add the checked attribute based on some condition. Say your box object has property checked which value is either "checked" or empty string ""

r += "<label for=\"id_%s_%d\" class=\"%s\"><input type=\"checkbox\" name=\"%s\" value=\"%s\" id=\"id_%s_%d\" %s /> %s</label>\n" % (
    boxes.name,
    i,
    cls,
    boxes.name,
    box.id,
    boxes.name,
    i,
    box.checked,
    box.name
)


Turns out the value I was looking for, the elements in the list that were "checked" isn't in the field, but rather part of the form object. I re-worked the template tag to look like this and it does exactly what I need:

@register.filter
def alignboxes(boxes, cls):

    r = ""
    i = 0
    for box in boxes.field.choices.queryset:
        checked = "checked=checked" if i in boxes.form.initial[boxes.name] else ""
        r += "<label for=\"id_%s_%d\" class=\"%s\"><input type=\"checkbox\" name=\"%s\" value=\"%s\" id=\"id_%s_%d\" %s /> %s</label>\n" % (
            boxes.name,
            i,
            cls,
            boxes.name,
            box.pk,
            boxes.name,
            i,
            checked,
            box.name
        )
        i = i + 1

    return r

For those who might come after, note that the checked value above was found in boxes.form.initial[boxes.name]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜