user6216224
user6216224

Reputation:

use_required_attribute() missing 1 required positional argument: 'initial' django forms

I wrote a dynamic form:

class VoteForm(forms.Form):
    def __init__(self, *args, **kwargs):
        question = kwargs.pop('instance', None)
        super().__init__(*args, **kwargs)

        if question:
            if question.allow_multiple_votes:
                choice_field = forms.ModelMultipleChoiceField(queryset=question.choice_set)
            else:
                choice_field = forms.ModelChoiceField(queryset=question.choice_set)
            choice_field.widget = forms.RadioSelect
            choice_field.label=False
            choice_field.empty_label=None
            choice_field.error_messages={'required': _('No choice selected.'),
                                         'invalid': _('Invalid choice selected.')}
            self.fields['choice'] = choice_field

Without the RadioSelect widget everything seems to work, but with it, the following error occurs:

TypeError: use_required_attribute() missing 1 required positional argument: 'initial'

Upvotes: 4

Views: 3791

Answers (2)

albar
albar

Reputation: 3100

When you set the widget after having created the field, it must be a widget instance, not the class itself. But you have to set choices yourself:

   choice_field.widget = forms.RadioSelect(choices=...)

Preferably, you can give the widget class when you construct your field:

   choice_field = forms.ModelChoiceField(queryset=question.choice_set, widget=forms.RadioSelect)

Upvotes: 6

John Moutafis
John Moutafis

Reputation: 23134

First things first, you have (assuming a typo) error in your widget declaration. You need an instance of the RadioSelect class as a widget:

choice_field.widget = forms.RadioSelect()   

Then you can set the initial value manually.
You can choose one of two options to do that:

Option 1:

Set initial at form instantiation:

if question.allow_multiple_votes:
            choice_field = forms.ModelMultipleChoiceField(
                queryset=question.choice_set,
                initial=0 
            )       
        else:
            choice_field = forms.ModelChoiceField(
                queryset=question.choice_set
                initial=0
            )

Option 2:

Set the initial attribute: choice_field.initial=0 (as @nik_m points out in the comments)


With initial=0 the first item of the queryset will be selected.

Upvotes: 2

Related Questions