Django ModelMultipleChoiceField object has no attribute to_field_name
Solution 1
You seem to have got confused between fields and widgets. You inherit from ModelMultipleChoiceField
, which (as the name implies) is a field, not a widget. But render
and render_options
are methods on widgets, not fields. And you've used your class in the widgets
dictionary.
I suspect you do mean to create a widget. You should inherit from a widget class, probably forms.CheckboxSelectMultiple
.
Solution 2
Not sure why it's a problem based on the code you've posted, but to_field_name
is an attribute on 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
However, when ModelMultipleChoiceField
subclasses ModelChoiceField
, it's __init__
method doesn't accept to_field_name
as an keyword argument. It apparently relies on the ModelChoiceField
's default behavior of setting self.to_field_name
the default of None
.
Your subclass should be doing the same, so that part is confusing.
intargc
Updated on June 17, 2022Comments
-
intargc almost 2 years
I'm trying to create a custom field for a ModelForm. I'm extending from ModelMultipleChoiceField and then overriding render and render_options, however, I keep getting this exception when just trying to import my form:
AttributeError: 'ModelMultipleChoiceField' object has no attribute 'to_field_name'
I'm not sure what I'm missing. I've tried even adding a to_field_name attribute to my new class, but that doesn't help. Here is my code:
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()) }
Whenever I simply do an
from myapp.forms import RoleForm
, I get the error above.Should I be adding something to my class that I'm missing?