2017-04-20 57 views
0

关于在django表单字段中为<option>标签添加属性,有一个很好的解释here。但这仅适用于Selectwidget。我想为SelectMultiplewidget做同样的事情。Django将属性添加到SelectMultiple <option>标签

我尝试以下(亚类SelectSelectMultiple和参考MySelectMultiple创建Model表单字段employees时):

class MySelect(forms.Select): 

    def __init__(self, *args, **kwargs): 
      super(MySelect, self).__init__(*args, **kwargs) 

    def render_option(self, selected_choices, option_value, option_label): 
     # original forms.Select code # 
     return u'<option custom_attribute="foo">...</option>' 

class MySelectMultiple(MySelect): 
    def __init__(self, *args, **kwargs): 
     super(MySelectMultiple, self).__init__(*args, **kwargs) 

employees = forms.ModelMultipleChoiceField(
        widget=MySelectMultiple(attrs={}), 
        queryset=Employee.objects.all(), 
       ) 

但呈现形式仍然呈现为Select插件,而不是一个SelectMultiple部件。

我可以提供attrs={'multiple':'multiple'}MySelectMultiple以使表单字段呈现为多选部件 - 但是当表单被保存时,只保存一个值(不是多个值)!

如何将表单渲染为多选字段并保存所有选定的值?谢谢。

+0

是员工领域一个manytomany字段 – Thameem

+0

@Thameem是的。但请参阅下面的答案。 – NickBraunagel

+0

默认情况下,manytomany字段将呈现为多重填充字段并在您调用form.save()时呈现。它会自动保存这些值。那么为什么你使用这个 – Thameem

回答

1

你选择倍数应该从SelectMultiple继承,而不是Select

class MySelectMultiple(SelectMultiple): 
    def render_option(self, selected_choices, option_value, option_label): 
     # original forms.Select code # 
     return u'<option custom_attribute="foo">...</option>' 

它看起来像你的__init__方法是没有必要的,因为它只是调用super()

+0

让我试试这个。谢谢。 – NickBraunagel

+0

你的答案与我的答案达到了相同的结果,但是我的行为违反了干,所以我要和你一起去。谢谢! – NickBraunagel

0

好了,想通了:使用:

class MySelectMultiple(MySelect): 
    def __init__(self, *args, **kwargs): 
     super(MySelectMultiple, self).__init__(*args, **kwargs) 

我还是用Django的本地Select只是调用它MySelectMultiple。我需要导入其余SelectMultiple

代替

所以:

class MySelectMultiple(MySelect): 
    def __init__(self, *args, **kwargs): 
     super(MySelectMultiple, self).__init__(*args, **kwargs) 

类需要完成(复制/原生的Django代码SelectMultiple贴):

class MySelectMultiple(MySelect): 
    allow_multiple_selected = True 

    def __init__(self, *args, **kwargs): 
     super(MySelectMultiple, self).__init__(*args, **kwargs) 


    def render(self, name, value, attrs=None, choices=()): 
     if value is None: 
      value = [] 
     final_attrs = self.build_attrs(attrs, name=name) 
     output = [format_html('<select multiple="multiple"{0}>', forms.utils.flatatt(final_attrs))] 
     options = self.render_options(choices, value) 
     if options: 
      output.append(options) 
     output.append('</select>') 
     return mark_safe('\n'.join(output)) 

    def value_from_datadict(self, data, files, name): 
     if isinstance(data, (MultiValueDict, MergeDict)): 
      return data.getlist(name) 
     return data.get(name, None)