From 69a3bb5d473c864124e57541e9dde8496da3ac15 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Sat, 19 Feb 2011 14:47:33 +0000 Subject: [PATCH] =?UTF-8?q?[1.2.X]=20Fixed=20#9161=20--=20Ensure=20that=20?= =?UTF-8?q?ModelMultipleChoiceField=20respects=20to=5Ffield=5Fname=20in=20?= =?UTF-8?q?validation.=20Thanks=20to=20Honza=20for=20the=20report,=20and?= =?UTF-8?q?=20Gregor=20M=C3=BCllegger=20for=20the=20patch.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of r15587 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15588 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/forms/models.py | 7 ++++--- tests/modeltests/model_forms/models.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/django/forms/models.py b/django/forms/models.py index 8cd5481e5a..860a748547 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -1017,13 +1017,14 @@ class ModelMultipleChoiceField(ModelChoiceField): 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) diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 4e7265ba74..d3a08ca760 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -1562,6 +1562,25 @@ ValidationError: [u'Select a valid choice. z is not one of the available choices +# 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]) +[] + +>>> 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': [, ]} + # Model field that returns None to exclude itself with explicit fields ######## >>> class CustomFieldForExclusionForm(ModelForm):