Opened 9 years ago
Closed 9 years ago
#27578 closed Bug (invalid)
ModelChoiceField.to_python() somehow receives value as type 'list'
| Reported by: | Julian | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | 1.9 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Whenever im running form.is_valid() i get the error:
Select a valid choice. That choice is not one of the available
choices.
Here is what I do in my view:
timeframes = HostTimeFrame.objects.all()
if request.method == 'POST':
form = SelectDatesForm(request.POST, timeframes=timeframes)
if form.is_valid():
pass
else:
form = SelectDatesForm(timeframes=timeframes)
My form does this:
class SelectDatesForm(forms.Form):
timeframes = forms.ModelChoiceField(queryset=HostTimeFrame.objects.none(), widget=forms.CheckboxSelectMultiple,
empty_label=None)
def __init__(self, *args, **kwargs):
qs = kwargs.pop('timeframes')
super(SelectDatesForm, self).__init__(*args, **kwargs)
self.fields['timeframes'].queryset = qs.order_by('start')
Ive been trying for hours to find where this actual validation is done, and realized the exception is raised in ModelChoiceField.to_python()
try:
key = self.to_field_name or 'pk'
value = self.queryset.get(**{key: value})
except (ValueError, TypeError, self.queryset.model.DoesNotExist):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
Where value is the primary key, but in List format, this raises an exception.
Change History (3)
follow-up: 2 comment:1 by , 9 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 9 years ago
comment:3 by , 9 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
If you're using widget=forms.CheckboxSelectMultiple then you need to use ModelMultipleChoiceField which accepts a list of values.
Replying to Julian Schneider:
Created my own bugfixes in a custom field:
class CustomModelChoiceField(ModelChoiceField): def to_python(self, value): if value in self.empty_values: return None try: key = self.to_field_name or 'pk' if type(value) == list: value = value[0] value = self.queryset.get(**{key: value}) except (ValueError, TypeError, self.queryset.model.DoesNotExist): raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice') return value