У объекта Django ModelMultipleChoiceField нет атрибута to_field_name - PullRequest
3 голосов
/ 18 ноября 2011

Я пытаюсь создать настраиваемое поле для ModelForm.Я расширяю ModelMultipleChoiceField, а затем переопределяю render и render_options, однако, я продолжаю получать это исключение, когда просто пытаюсь импортировать мою форму:

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, я получаю ошибку выше.

Должен ли я добавить что-то в свой класс, что мне не хватает?

Ответы [ 2 ]

16 голосов
/ 19 ноября 2011

Вы, похоже, запутались между полями и виджетами.Вы наследуете от ModelMultipleChoiceField, который (как следует из названия) является полем, а не виджетом.Но render и render_options - это методы для виджетов, а не полей.И вы использовали свой класс в словаре widgets.

Я подозреваю, что вы действительно хотите создать виджет.Вы должны наследовать от класса виджета, вероятно, forms.CheckboxSelectMultiple.

2 голосов
/ 19 ноября 2011

Не знаю, почему это проблема, основанная на опубликованном вами коде, но to_field_name является атрибутом ModelChoiceField:

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

Однако, когда ModelMultipleChoiceField подклассы ModelChoiceField,метод __init__ не принимает to_field_name в качестве аргумента ключевого слова.По-видимому, он опирается на поведение ModelChoiceField по умолчанию, устанавливающее self.to_field_name по умолчанию None.

Ваш подкласс должен делать то же самое, поэтому эта часть сбивает с толку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...