2011-11-18 111 views
3

我正在嘗試爲ModelForm創建一個自定義字段。我是從ModelMultipleChoiceField然而延伸,然後重寫渲染和render_options,我不斷收到此異常時,只是試圖導入我的表格:Django ModelMultipleChoiceField對象沒有屬性to_field_name

AttributeError: 'ModelMultipleChoiceField' object has no attribute 'to_field_name'

我不知道我錯過了什麼。我試過在我的新類中添加to_field_name屬性,但這並沒有幫助。這裏是我的代碼:

class MultiSelect(ModelMultipleChoiceField): 
def __init__(self, queryset, cache_choices=False, required=True, 
      widget=None, label=None, initial=None, help_text=None, *args, **kwargs): 
    super(MultiSelect, self).__init__(queryset, cache_choices, required, widget, 
      label, initial, help_text, *args, **kwargs) 

def render_options(self, name, choices, selected_choices): 
    output = [] 
    i = 0 
    for option_value, option_label in chain(self.choices, choices): 
     checked_html = (option_value in selected_choices) and u' checked="checked"' or '' 
     class_html = (i % 2 == 0) and u'even' or u'odd' 
     output.append('<li class="{0}"><input type="checkbox" name="{1}" value="{2}"{3}/>{4}</li>' 
       .format(class_html, name, escape(option_value), checked_html, escape(option_label))) 
     i += 1 

def render(self, name, value, attrs=None, choices=()): 
    if value is None: value = [] 
    final_attrs = self.build_attrs(attrs, name=name) 
    output = [u'<ul class="multiSelect">'] 
    options = self.render_options(name, choices, value) 
    if options: 
     output.append(options) 
    output.append('</ul>') 
    return mark_safe(u'\n'.join(output)) 


class RoleForm(ModelForm): 
    class Meta: 
     model = Role 
     exclude = ('user_id',) 
     widgets = { 
      'permissions': MultiSelect(queryset=Permission.objects.all()) 
     } 

每當我簡單地做一個from myapp.forms import RoleForm,我會得到上面的錯誤。

我應該向我的班級添加一些我錯過的東西嗎?

回答

12

您似乎對字段和小部件感到困惑。您從ModelMultipleChoiceField繼承,它(正如其名稱所暗示的)是一個字段,而不是一個小部件。但是renderrender_options是小部件上的方法,而不是字段。你已經在widgets字典中使用過你的課程。

我懷疑你的意思是創建一個小部件。你應該繼承一個widget類,可能是forms.CheckboxSelectMultiple

+0

是的,你說得對。我是...和CheckboxSelectMultiple是我一直在尋找的東西!我怎麼想那個?謝謝。現在要弄清楚如何刪除惱人的help_text消息。 – intargc

1

不知道爲什麼它是一個基於你已經發布的代碼有問題,但to_field_nameModelChoiceField屬性:

class ModelChoiceField(ChoiceField): 
    ... 

    def __init__(self, queryset, empty_label=u"---------", cache_choices=False, 
       required=True, widget=None, label=None, initial=None, 
       help_text=None, to_field_name=None, *args, **kwargs): 
     ...    

     self.to_field_name = to_field_name 

然而,當ModelMultipleChoiceFieldModelChoiceField,這是__init__方法不接受to_field_name爲一個關鍵字參數。它顯然依靠ModelChoiceField的默認行爲設置self.to_field_name默認爲None

你的子類應該做同樣的事情,這部分是混亂的。

相關問題