Django CheckboxSelectMultiple覆盖ModelForm中的"选项"

qdo*_*dot 2 django django-forms

我希望能够以我的django形式提取不同的信息:

这是我的形式:

<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>

class InstanceForm(ModelForm):
    class Meta:
        model = models.BaseAsset
        widgets = {
            'labels': LabelIconCheckboxSelectMultiple()
        }
Run Code Online (Sandbox Code Playgroud)

该模型:

class AssetClass(models.Model):
    default_labels = models.ManyToManyField(Label, null=True, blank=True)
    pass
Run Code Online (Sandbox Code Playgroud)

M2M参考字段

class Label(models.Model):
    explanation = models.CharField(null=True, max_length=63)
    svgpreview  = models.CharField(null=True, max_length=31)
    def __unicode__(self):
        return unicode(self.explanation)
    pass
Run Code Online (Sandbox Code Playgroud)

现在,生成的HTML代码{{ form.as_p }}如下:

<li><label for="id_labels_0"><input type="checkbox" name="labels" value="1" id="id_labels_0" /> Consult owner before using</label></li>
<li><label for="id_labels_1"><input type="checkbox" name="labels" value="2" id="id_labels_1" /> This item is broken</label></li>
Run Code Online (Sandbox Code Playgroud)

这意味着它显然使用__unicode__了模型'Label' 的渲染.如何在"选择"小部件中更改该行为,以便它使用不同的函数来填充它的选择?我试图以合理的便携方式'<img src="{{label.svgpreview}}" alt="{{label.explanation}}"...>'在复选框旁打印?

asd*_*hak 5

你将覆盖forms.widgets.CheckboxSelectMultiple类:

这是CheckboxSelectMultiple类及其渲染功能:

class CheckboxSelectMultiple(SelectMultiple):
    def render(self, name, value, attrs=None, choices=()):
        if value is None: value = []
        has_id = attrs and 'id' in attrs
        final_attrs = self.build_attrs(attrs, name=name)
        output = [u'<ul>']
        # Normalize to strings
        str_values = set([force_unicode(v) for v in value])
        for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
            # If an ID attribute was given, add a numeric index as a suffix,
            # so that the checkboxes don't all have the same ID attribute.
            if has_id:
                final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
                label_for = u' for="%s"' % final_attrs['id']
            else:
                label_for = ''

            cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
            option_value = force_unicode(option_value)
            rendered_cb = cb.render(name, option_value)
            option_label = conditional_escape(force_unicode(option_label))
            output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label))
        output.append(u'</ul>')
        return mark_safe(u'\n'.join(output))
Run Code Online (Sandbox Code Playgroud)

那你要做什么:

class MyCheckboxSelectMultiple(CheckboxSelectMultiple):
    def render(self, name, value, attrs=None, choices=()):
        #put your code to have custom checkbox control with icon
        #...
        output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label)) # especially you will be working on this line
        #...
Run Code Online (Sandbox Code Playgroud)

然后你会在哪里使用widgets=CheckboxSelectMultiple()widgets=MyCheckboxSelectMultiple()