Tomasz Brzezina
Tomasz Brzezina

Reputation: 1534

ModelMultipleChoiceField' object has no attribute 'to_field_name'

These are my files:

models.py:

class Pierwszy(models.model):
   name = models.CharField(max_length=15,blank =True, null= True)
   extra = models.CharField(max_length=15,blank =True, null= True)
   kids = models.ManyToManyField('Pierwszy', related_name="pierwszy_children", null=True, blank=True)

class Drugi(Pierwszy):
   ext_name = models.CharField(max_length=15,blank =True, null= True)

views.py:

class DrugiForm(ModelForm):
  def __init__(self, *args, **kwargs):
    super(DrugiForm, self).__init__(*args, **kwargs)
    instance = getattr(self, 'instance', None)
    if instance and instance.pk:
      if instance.name is not None:
        self.fields['name'].widget.attrs['readonly'] = True

   class Meta:
     model = Drugi
     fields = ('ext_name','name','kids','extra')
     widgets = {
      'kids' : forms.ModelMultipleChoiceField(queryset=None, widget=forms.CheckboxSelectMultiple()),
     }
     hidden = {
       'extra'
     }

template:

<form method="post">{% csrf_token %}
{{ form.non_field_errors }}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
  <div class="fieldWrapper">
    {{ field.errors }}
    {{ field.label_tag }}: {{ field }}
  </div>
{% endfor %}
  <p><input type="submit" value="Send message" /></p>
</form>

On this stage I just want to see the current state of object. I don't want to edit fields.

I use queryset=None for kids' widget, because I don't want to show all possibilities, just show list of names (name field) connected to instance.

i'm not sure where should I add filter to queryset (in widget def or in init), but the biggest problem is that, whatever I do, I get

ModelMultipleChoiceField' object has no attribute 'to_field_name'

And I'm stacked now. On Google there's only one case, but this is about overriding the widget/Field - which is not my case.

Upvotes: 0

Views: 2668

Answers (1)

Rod Xavier
Rod Xavier

Reputation: 4043

The widgets dictionary expects the values to be widget instances such as TextArea(), TextInput(), etc.

If you want to use forms.ModelMultipleChoiceField, you could do something like this

class DrugiForm(ModelForm):
    kids = forms.ModelMultipleChoiceField(queryset=Pierwszy.objects.none(), widget=forms.CheckboxSelectMultiple())

    def __init__(self, *args, **kwargs):
        super(DrugiForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
        if instance.name is not None:
            self.fields['name'].widget.attrs['readonly'] = True

    class Meta:
        model = Drugi
        fields = ('ext_name','name','kids','extra')

Upvotes: 1

Related Questions