summaryrefslogtreecommitdiff
path: root/django/forms
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2013-01-26 17:05:47 +0100
committerClaude Paroz <claude@2xlibre.net>2013-03-01 09:35:04 +0100
commit892bc91cb0036d6868081363628f65094c4790d6 (patch)
tree511612fec701faeaeaa52531364d7337baee7e6b /django/forms
parent0c82b1dfc48b4870e8fbcfb782ae02cdca821e1f (diff)
Fixed #16612 -- Improved has_changed detection for localized field values
Thanks Simon Charette for the review.
Diffstat (limited to 'django/forms')
-rw-r--r--django/forms/fields.py22
-rw-r--r--django/forms/forms.py4
-rw-r--r--django/forms/models.py16
3 files changed, 24 insertions, 18 deletions
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 277f0b093e..c7ed085b16 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -184,17 +184,13 @@ class Field(object):
# For purposes of seeing whether something has changed, None is
# the same as an empty string, if the data or inital value we get
# is None, replace it w/ ''.
- if data is None:
- data_value = ''
- else:
- data_value = data
- if initial is None:
- initial_value = ''
- else:
- initial_value = initial
- if force_text(initial_value) != force_text(data_value):
+ initial_value = initial if initial is not None else ''
+ try:
+ data = self.to_python(data)
+ except ValidationError:
return True
- return False
+ data_value = data if data is not None else ''
+ return initial_value != data_value
def __deepcopy__(self, memo):
result = copy.copy(self)
@@ -392,12 +388,6 @@ class BaseTemporalField(Field):
def strptime(self, value, format):
raise NotImplementedError('Subclasses must define this method.')
- def _has_changed(self, initial, data):
- try:
- data = self.to_python(data)
- except ValidationError:
- return True
- return self.to_python(initial) != data
class DateField(BaseTemporalField):
widget = DateInput
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 20a2e426bb..38601432bc 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -345,8 +345,8 @@ class BaseForm(object):
else:
initial_prefixed_name = self.add_initial_prefix(name)
hidden_widget = field.hidden_widget()
- initial_value = hidden_widget.value_from_datadict(
- self.data, self.files, initial_prefixed_name)
+ initial_value = field.to_python(hidden_widget.value_from_datadict(
+ self.data, self.files, initial_prefixed_name))
if hasattr(field.widget, '_has_changed'):
warnings.warn("The _has_changed method on widgets is deprecated,"
" define it at field level instead.",
diff --git a/django/forms/models.py b/django/forms/models.py
index 3905e9e902..1cea110df4 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -1012,6 +1012,11 @@ class ModelChoiceField(ChoiceField):
def validate(self, value):
return Field.validate(self, value)
+ def _has_changed(self, initial, data):
+ initial_value = initial if initial is not None else ''
+ data_value = data if data is not None else ''
+ return force_text(self.prepare_value(initial_value)) != force_text(data_value)
+
class ModelMultipleChoiceField(ModelChoiceField):
"""A MultipleChoiceField whose choices are a model QuerySet."""
widget = SelectMultiple
@@ -1059,3 +1064,14 @@ class ModelMultipleChoiceField(ModelChoiceField):
not hasattr(value, '_meta')):
return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value]
return super(ModelMultipleChoiceField, self).prepare_value(value)
+
+ def _has_changed(self, initial, data):
+ if initial is None:
+ initial = []
+ if data is None:
+ data = []
+ if len(initial) != len(data):
+ return True
+ initial_set = set([force_text(value) for value in initial])
+ data_set = set([force_text(value) for value in data])
+ return data_set != initial_set