ModelChoiceField queryset forms + optional django forms selection fields

I am trying to create a form in loading ModelChoiceField from a set of queries, and I want to add some additional values ​​to ModelChoiceField for extension. I used the selection box as shown below, but when updating the form, below the error

Form Error: Select the correct one. This selection is not one of the available options.

The code:

self.fields['lead'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(poc__in = ('lead','sr.lead'))) self.fields['lead2'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(role__in = ('lead','sr.lead'))) choice_field = self.fields['lead'] choice_field.choices = list(choice_field.choices) + [('None', 'None')] choice_field = self.fields['lead2'] choice_field.choices = list(choice_field.choices) + [('None', 'None')] 

Am I doing something wrong here?

+7
source share
3 answers

This will not work. See how ModelChoiceField works:

 try: key = self.to_field_name or 'pk' value = self.queryset.get(**{key: value}) except self.queryset.model.DoesNotExist: raise ValidationError(self.error_messages['invalid_choice']) return value 

You cannot add anything randomly to this.

Instead, use ChoiceField and do custom data processing.

 class TestForm(forms.Form): mychoicefield = forms.ChoiceField(choices=QS_CHOICES) def __init__(self, *args, **kwargs): super(TestForm, self).__init__(*args, **kwargs) self.fields['mychoicefield'].choices = \ list(self.fields['mychoicefield'].choices) + [('new stuff', 'new')] def clean_mychoicefield(self): data = self.cleaned_data.get('mychoicefield') if data in QS_CHOICES: try: data = MyModel.objects.get(id=data) except MyModel.DoesNotExist: raise forms.ValidationError('foo') return data 
+16
source

It looks like you just want these form fields to be optional. Do not make it hard for yourself. See documentation for marking a form field as needed.

 lead = forms.ModelChoiceField(queryset=People.objects.filter(poc__in=('lead', 'sr.lead')), required=False) 
+3
source

Do you have a Person object with pk 'None'?

I think you should use

 self.fields['lead'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(poc__in = ('lead','sr.lead')), empty_label="None") self.fields['lead2'] = forms.ModelChoiceField(queryset = Pepole.objects.filter(role__in = ('lead','sr.lead')), empty_label="None") 

edit:

Since you are using the modelchoicefield field, I think that all of your options will be either model type or none.

You can "expand" the choice of this type by changing the query that you pass to the constructor for the modlechoice field, for example:

 qs = People.objects.filter(poc__in = ('lead','sr.lead')) ext = People.objects.filter(role__in = ('lead', 'sr.lead')) qs = qs | ext self.fields['lead'] = forms.ModelChoiceField(queryset = qs, empty_label='None') or for updating self.fields['lead'].queryset = qs 

this question says a little about modelchoicefield and may interest you:

How to filter ForeignKey options in Django ModelForm?

+1
source

All Articles