@@ -1221,8 +1221,7 @@ def __init__(self, queryset, cache_choices=False, required=True,
12211221 def to_python (self , value ):
12221222 if not value :
12231223 return []
1224- to_py = super (ModelMultipleChoiceField , self ).to_python
1225- return [to_py (val ) for val in value ]
1224+ return list (self ._check_values (value ))
12261225
12271226 def clean (self , value ):
12281227 if self .required and not value :
@@ -1231,7 +1230,29 @@ def clean(self, value):
12311230 return self .queryset .none ()
12321231 if not isinstance (value , (list , tuple )):
12331232 raise ValidationError (self .error_messages ['list' ], code = 'list' )
1233+ qs = self ._check_values (value )
1234+ # Since this overrides the inherited ModelChoiceField.clean
1235+ # we run custom validators here
1236+ self .run_validators (value )
1237+ return qs
1238+
1239+ def _check_values (self , value ):
1240+ """
1241+ Given a list of possible PK values, returns a QuerySet of the
1242+ corresponding objects. Raises a ValidationError if a given value is
1243+ invalid (not a valid PK, not in the queryset, etc.)
1244+ """
12341245 key = self .to_field_name or 'pk'
1246+ # deduplicate given values to avoid creating many querysets or
1247+ # requiring the database backend deduplicate efficiently.
1248+ try :
1249+ value = frozenset (value )
1250+ except TypeError :
1251+ # list of lists isn't hashable, for example
1252+ raise ValidationError (
1253+ self .error_messages ['list' ],
1254+ code = 'list' ,
1255+ )
12351256 for pk in value :
12361257 try :
12371258 self .queryset .filter (** {key : pk })
@@ -1250,9 +1271,6 @@ def clean(self, value):
12501271 code = 'invalid_choice' ,
12511272 params = {'value' : val },
12521273 )
1253- # Since this overrides the inherited ModelChoiceField.clean
1254- # we run custom validators here
1255- self .run_validators (value )
12561274 return qs
12571275
12581276 def prepare_value (self , value ):
0 commit comments