How to update form with MultipleChoiceField?

When I want to send data to be updated just do:

def MyView(request, pk):
    instance = get_object_or_404(Mymodel, id=pk)
    form = Myform(request.POST or None, instance=instance)

But when I do this for a form that has a single field of multiple choices (MultipleChoiceField) it goes wrong.

forms.py

class FormChoices(forms.Form):
    result = forms.MultipleChoiceField(
                            choices=(MyModel.objects.values_list("id","name")),
                                    widget=forms.CheckboxSelectMultiple(),
                 label="Select")

views.py

def MyViewChoices(request, pk):

     instance = MyModel.objects.values_list('id','name' ).filter(id=pk)
     form = FormChoices(request.POST or None, instance=instance)

I get the following error:

__init__() got an unexpected keyword argument 'instance'

How can I send data to this form (FormChoices) to show all items and those that have been registered appear marked?

instance is only for ModelForm classes. You want initial to set the initial data for a field on a normal form.

1 Like

Thank you, I didn’t know that difference.

I modified the view like this:

def MyViewChoices(request, pk):

     instance = MyModel.objects.values_list('id','name' ).filter(id=pk)
     form = FormChoices(request.POST or None, initial={'result': instance})

Now the template is render. But the checkboxes don’t appear marked with the sent items.

My objective is that sent items appear marked among all available items. It is possible?

The only way that I know of to do this is in your __init__ method in your form.

You’ve got two different things you’re trying to do here, one is to get the list of all available choices, the other is to identify the ones previously selected. You want to ensure that the form field is defined for all available choices, then modify that field to show which ones are already selected.

For a greatly simplified example:

class FormChoices(forms.Form):
    result = forms.MultipleChoiceField(
                            choices=(MyModel.objects.values_list("id","name")),
                                    widget=forms.CheckboxSelectMultiple(),
                 label="Select")
    ...
    def __init__(self, *args, **kwargs):
        ...
        super().__init__(*args, **kwargs)
        ....
        # Some query to get the list of IDs to mark as selected
        ...
        self.initial['result'] = <list of ids to mark as selected>