Moved has_changed logic from widget to form field

Refs #16612. Thanks Aymeric Augustin for the suggestion.
This commit is contained in:
Claude Paroz 2013-01-25 20:50:46 +01:00
parent ce27fb198d
commit ebb504db69
14 changed files with 230 additions and 251 deletions

View file

@ -208,25 +208,6 @@ class Widget(six.with_metaclass(MediaDefiningClass)):
"""
return data.get(name, None)
def _has_changed(self, initial, data):
"""
Return True if data differs from initial.
"""
# 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):
return True
return False
def id_for_label(self, id_):
"""
Returns the HTML ID attribute of this Widget for use by a <label>,
@ -325,10 +306,6 @@ class FileInput(Input):
"File widgets take data from FILES, not POST"
return files.get(name, None)
def _has_changed(self, initial, data):
if data is None:
return False
return True
FILE_INPUT_CONTRADICTION = object()
@ -426,17 +403,6 @@ class DateInput(TextInput):
return value.strftime(self.format)
return value
def _has_changed(self, initial, data):
# If our field has show_hidden_initial=True, initial will be a string
# formatted by HiddenInput using formats.localize_input, which is not
# necessarily the format used for this widget. Attempt to convert it.
try:
input_format = formats.get_format('DATE_INPUT_FORMATS')[0]
initial = datetime.datetime.strptime(initial, input_format).date()
except (TypeError, ValueError):
pass
return super(DateInput, self)._has_changed(self._format_value(initial), data)
class DateTimeInput(TextInput):
def __init__(self, attrs=None, format=None):
@ -456,17 +422,6 @@ class DateTimeInput(TextInput):
return value.strftime(self.format)
return value
def _has_changed(self, initial, data):
# If our field has show_hidden_initial=True, initial will be a string
# formatted by HiddenInput using formats.localize_input, which is not
# necessarily the format used for this widget. Attempt to convert it.
try:
input_format = formats.get_format('DATETIME_INPUT_FORMATS')[0]
initial = datetime.datetime.strptime(initial, input_format)
except (TypeError, ValueError):
pass
return super(DateTimeInput, self)._has_changed(self._format_value(initial), data)
class TimeInput(TextInput):
def __init__(self, attrs=None, format=None):
@ -485,17 +440,6 @@ class TimeInput(TextInput):
return value.strftime(self.format)
return value
def _has_changed(self, initial, data):
# If our field has show_hidden_initial=True, initial will be a string
# formatted by HiddenInput using formats.localize_input, which is not
# necessarily the format used for this widget. Attempt to convert it.
try:
input_format = formats.get_format('TIME_INPUT_FORMATS')[0]
initial = datetime.datetime.strptime(initial, input_format).time()
except (TypeError, ValueError):
pass
return super(TimeInput, self)._has_changed(self._format_value(initial), data)
# Defined at module level so that CheckboxInput is picklable (#17976)
def boolean_check(v):
@ -530,13 +474,6 @@ class CheckboxInput(Widget):
value = values.get(value.lower(), value)
return bool(value)
def _has_changed(self, initial, data):
# Sometimes data or initial could be None or '' which should be the
# same thing as False.
if initial == 'False':
# show_hidden_initial may have transformed False to 'False'
initial = False
return bool(initial) != bool(data)
class Select(Widget):
allow_multiple_selected = False
@ -612,14 +549,6 @@ class NullBooleanSelect(Select):
'False': False,
False: False}.get(value, None)
def _has_changed(self, initial, data):
# For a NullBooleanSelect, None (unknown) and False (No)
# are not the same
if initial is not None:
initial = bool(initial)
if data is not None:
data = bool(data)
return initial != data
class SelectMultiple(Select):
allow_multiple_selected = True
@ -639,16 +568,6 @@ class SelectMultiple(Select):
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
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
@python_2_unicode_compatible
class RadioInput(SubWidget):
@ -844,17 +763,6 @@ class MultiWidget(Widget):
def value_from_datadict(self, data, files, name):
return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
def _has_changed(self, initial, data):
if initial is None:
initial = ['' for x in range(0, len(data))]
else:
if not isinstance(initial, list):
initial = self.decompress(initial)
for widget, initial, data in zip(self.widgets, initial, data):
if widget._has_changed(initial, data):
return True
return False
def format_output(self, rendered_widgets):
"""
Given a list of rendered widgets (as strings), returns a Unicode string