Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.2.X] Fixed #9161 -- Ensure that ModelMultipleChoiceField respects …

…to_field_name in validation. Thanks to Honza for the report, and Gregor Müllegger for the patch.

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
  • Loading branch information...
commit 69a3bb5d473c864124e57541e9dde8496da3ac15 1 parent 626ad2c
Russell Keith-Magee authored February 19, 2011
7  django/forms/models.py
@@ -1017,13 +1017,14 @@ def clean(self, value):
1017 1017
             return []
1018 1018
         if not isinstance(value, (list, tuple)):
1019 1019
             raise ValidationError(self.error_messages['list'])
  1020
+        key = self.to_field_name or 'pk'
1020 1021
         for pk in value:
1021 1022
             try:
1022  
-                self.queryset.filter(pk=pk)
  1023
+                self.queryset.filter(**{key: pk})
1023 1024
             except ValueError:
1024 1025
                 raise ValidationError(self.error_messages['invalid_pk_value'] % pk)
1025  
-        qs = self.queryset.filter(pk__in=value)
1026  
-        pks = set([force_unicode(o.pk) for o in qs])
  1026
+        qs = self.queryset.filter(**{'%s__in' % key: value})
  1027
+        pks = set([force_unicode(getattr(o, key)) for o in qs])
1027 1028
         for val in value:
1028 1029
             if force_unicode(val) not in pks:
1029 1030
                 raise ValidationError(self.error_messages['invalid_choice'] % val)
19  tests/modeltests/model_forms/models.py
@@ -1562,6 +1562,25 @@ class FlexibleDatePost(models.Model):
1562 1562
 <tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr>
1563 1563
 <tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>
1564 1564
 
  1565
+# to_field_name should also work on ModelMultipleChoiceField ##################
  1566
+
  1567
+>>> field = ModelMultipleChoiceField(Inventory.objects.all(), to_field_name='barcode')
  1568
+>>> for choice in field.choices:
  1569
+...     print choice
  1570
+(86, u'Apple')
  1571
+(22, u'Pear')
  1572
+(87, u'Core')
  1573
+>>> field.clean([86])
  1574
+[<Inventory: Apple>]
  1575
+
  1576
+>>> class SelectInventoryForm(forms.Form):
  1577
+...     items = ModelMultipleChoiceField(Inventory.objects.all(), to_field_name='barcode')
  1578
+>>> form = SelectInventoryForm({'items': [87, 22]})
  1579
+>>> form.is_valid()
  1580
+True
  1581
+>>> form.cleaned_data
  1582
+{'items': [<Inventory: Pear>, <Inventory: Core>]}
  1583
+
1565 1584
 # Model field that returns None to exclude itself with explicit fields ########
1566 1585
 
1567 1586
 >>> class CustomFieldForExclusionForm(ModelForm):

0 notes on commit 69a3bb5

Please sign in to comment.
Something went wrong with that request. Please try again.