【问题标题】:django modelmultiplechoicefield and widget checkboxselectmultipledjango modelmultiplechoicefield和widget checkboxselectmultiple
【发布时间】:2013-03-31 01:40:29
【问题描述】:

我想要管理界面之类的东西。

这是表单的代码:

class NewRoleFrom(forms.Form):
    role = forms.ModelMultipleChoiceField(
        queryset=Role.objects.all(),
        widget=forms.CheckboxSelectMultiple
    )

所以,这很简单,我有角色标签(Role:),然后数据库中的每个角色都用一个复选框呈现。 像这样我可以取回用户选择的所有角色对象。 但是在每行的开头我都有一个项目符号,我该如何删除它? 那么是否可以像我们在 list_display 中定义 admin.py 时一样添加其他属性?

【问题讨论】:

    标签: python django django-forms django-admin


    【解决方案1】:

    这是来自 django.forms.widgets 模块的那个小部件的源代码:

    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))
    
        def id_for_label(self, id_):
            # See the comment for RadioSelect.id_for_label()
            if id_:
                id_ += '_0'
            return id_
    

    您可以看到项目符号是由于 django CSS 用于列表。因此,要删除它们,请考虑创建一个继承自 CheckboxSelectMultiple 的新 wudget,并在“ul”html 标记中添加一个类,然后添加您自己的 css 并使用详细的解决方案 here

    【讨论】:

      【解决方案2】:

      在您的表单模板中,只需遍历角色

      form.html

      {% for role in form.role %}
          <div class="checkbox">
            {{ role }}
          </div>
      {% endfor %}
      

      然后用 css 完善一下。

      【讨论】:

        【解决方案3】:

        我会用一个自定义类覆盖 CheckboxSelectMultiple 类,并直接在渲染输出中插入样式更改。见下面的代码

        class CustomCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
            def __init__(self, attrs=None):
                super(CustomCheckboxSelectMultiple, self).__init__(attrs)
        
            def render(self, name, value, attrs=None, choices=()):
                output = super(CustomCheckboxSelectMultiple, self).render(name, value, attrs, choices)
        
                style = self.attrs.get('style', None)
                if style:
                    output = output.replace("<ul", format_html('<ul style="{0}"', style))
        
                return mark_safe(output)
        

        然后以你的形式:

        class NewRoleFrom(forms.Form):
            role = forms.ModelMultipleChoiceField(
                queryset=Role.objects.all(),
                widget=CustomCheckboxSelectMultiple(attrs={'style': 'list-style: none; margin: 0;'})
            )
        

        【讨论】:

          猜你喜欢
          • 2018-08-02
          • 2019-03-03
          • 2016-10-17
          • 2018-10-18
          • 2018-12-09
          • 1970-01-01
          • 2012-04-06
          • 2012-03-19
          • 2014-09-29
          相关资源
          最近更新 更多