Skip to content

Commit

Permalink
Fixed #9161 -- Ensure that ModelMultipleChoiceField respects to_field…
Browse files Browse the repository at this point in the history
…_name in validation. Thanks to Honza for the report, and Gregor Müllegger for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15587 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
freakboy3742 committed Feb 19, 2011
1 parent 75a1aaa commit 1abf126
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
7 changes: 4 additions & 3 deletions django/forms/models.py
Expand Up @@ -1006,13 +1006,14 @@ def clean(self, value):
return []
if not isinstance(value, (list, tuple)):
raise ValidationError(self.error_messages['list'])
key = self.to_field_name or 'pk'
for pk in value:
try:
self.queryset.filter(pk=pk)
self.queryset.filter(**{key: pk})
except ValueError:
raise ValidationError(self.error_messages['invalid_pk_value'] % pk)
qs = self.queryset.filter(pk__in=value)
pks = set([force_unicode(o.pk) for o in qs])
qs = self.queryset.filter(**{'%s__in' % key: value})
pks = set([force_unicode(getattr(o, key)) for o in qs])
for val in value:
if force_unicode(val) not in pks:
raise ValidationError(self.error_messages['invalid_choice'] % val)
Expand Down
19 changes: 19 additions & 0 deletions tests/modeltests/model_forms/models.py
Expand Up @@ -1562,6 +1562,25 @@ class FlexibleDatePost(models.Model):
<tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr>
<tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>
# to_field_name should also work on ModelMultipleChoiceField ##################
>>> field = ModelMultipleChoiceField(Inventory.objects.all(), to_field_name='barcode')
>>> for choice in field.choices:
... print choice
(86, u'Apple')
(22, u'Pear')
(87, u'Core')
>>> field.clean([86])
[<Inventory: Apple>]
>>> class SelectInventoryForm(forms.Form):
... items = ModelMultipleChoiceField(Inventory.objects.all(), to_field_name='barcode')
>>> form = SelectInventoryForm({'items': [87, 22]})
>>> form.is_valid()
True
>>> form.cleaned_data
{'items': [<Inventory: Pear>, <Inventory: Core>]}
# Model field that returns None to exclude itself with explicit fields ########
>>> class CustomFieldForExclusionForm(ModelForm):
Expand Down

0 comments on commit 1abf126

Please sign in to comment.