[Django]-Django: ModelMultipleChoiceField doesn't select initial choices

16๐Ÿ‘

โœ…

You will need to add an __init__ method to Action_Form to set your initial values, remembering to call __init__ on the base ModelForm class via super.

class Action_Form(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(Action_Form, self).__init__(*args, **kwargs)
        self.fields['from_company'].queryset = Contact.object.filter(...

If you plan to pass your filter params as keyword args to Action_Form, youโ€™ll need to remove them prior invoking super:

myfilter = kwargs['myfilter']
del kwargs['myfilter']

or, probably better:

myfilter = kwargs.pop('myfilter')

For more information, hereโ€™s another link referring to Dynamic ModelForms in Django.

๐Ÿ‘คJeff Bauer

23๐Ÿ‘

Iโ€™m replying for 1)

1. How can I make ModelMultipleChoiceField take those โ€œinitialโ€ values?

This could be done in your Action_Form __init__ method using ModelMultipleChoiceField initial attribute.

As it says in the Django source code (db/models/fields/related.py)
in def formfield(self, **kwargs):

        # If initial is passed in, it's a list of related objects, but the
        # MultipleChoiceField takes a list of IDs.

So you need to give it a list of IDs:

class Action_Form(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(Action_Form, self).__init__(*args, **kwargs)
        self.fields['from_company'].initial = [c.pk for c in Contact.object.filter()]
๐Ÿ‘คAndre Miras

13๐Ÿ‘

If previous answer wasn't straight-forward enough, I try to answer 1) again:

  1. How can I make ModelMultipleChoiceField take those "initial" values?

You can leave Action_Form as it was in the original question, and just use this to render exactly what you want:

>>> form4 = Action_Form(initial={'from_company': Contact.objects.all().values_list('id',flat=True)})
>>> print form4['from_company']
๐Ÿ‘คygneo

12๐Ÿ‘

Answer to (1) question!

This will not work:

self.fields['from_company'].initial = [c.pk for c in Contact.object.filter()]

But this will really work:

self.initial['from_company'] = [c.pk for c in Contact.object.filter()]
๐Ÿ‘คAlbert Tugushev

0๐Ÿ‘

The problem is because the Contact.objects.all().values_list('id', flat=True) if a QuerySet object, the MultipleChoiceField needs a list, see in the doc

To fix this, you need to convert the QuerySet to a list!

Exempla:

contacts = list(Contact.objects.values_list('id', flat=True))
form = Action_Form({'from_company': contacts})

Leave a comment