diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py index 16e617301b..02cecca9aa 100644 --- a/django/newforms/widgets.py +++ b/django/newforms/widgets.py @@ -401,6 +401,18 @@ class SelectMultiple(Widget): if isinstance(data, MultiValueDict): return data.getlist(name) return data.get(name, None) + + def _has_changed(self, initial, data): + if initial is None: + initial = [] + if data is None: + data = [] + if len(initial) != len(data): + return True + for value1, value2 in zip(initial, data): + if force_unicode(value1) != force_unicode(value2): + return True + return False class RadioInput(StrAndUnicode): """ diff --git a/tests/regressiontests/forms/widgets.py b/tests/regressiontests/forms/widgets.py index 4944a26b74..e20ea15175 100644 --- a/tests/regressiontests/forms/widgets.py +++ b/tests/regressiontests/forms/widgets.py @@ -612,6 +612,20 @@ If 'choices' is passed to both the constructor and render(), then they'll both b >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) u'' +# Test the usage of _has_changed +>>> w._has_changed(None, None) +False +>>> w._has_changed([], None) +False +>>> w._has_changed(None, [u'1']) +True +>>> w._has_changed([1, 2], [u'1', u'2']) +False +>>> w._has_changed([1, 2], [u'1']) +True +>>> w._has_changed([1, 2], [u'1', u'3']) +True + # RadioSelect Widget ########################################################## >>> w = RadioSelect() @@ -910,6 +924,20 @@ If 'choices' is passed to both the constructor and render(), then they'll both b
+# Test the usage of _has_changed +>>> w._has_changed(None, None) +False +>>> w._has_changed([], None) +False +>>> w._has_changed(None, [u'1']) +True +>>> w._has_changed([1, 2], [u'1', u'2']) +False +>>> w._has_changed([1, 2], [u'1']) +True +>>> w._has_changed([1, 2], [u'1', u'3']) +True + # Unicode choices are correctly rendered as HTML >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) u'