2017-04-20 31 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)