Skip to content

Commit

Permalink
Fixed #23162 -- Renamed forms.Field._has_changed() to has_changed().
Browse files Browse the repository at this point in the history
  • Loading branch information
gmunumel authored and timgraham committed Aug 15, 2014
1 parent 99561ee commit deed00c
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 67 deletions.
2 changes: 1 addition & 1 deletion django/contrib/auth/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def bound_data(self, data, initial):
# render an input field.
return initial

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
return False


Expand Down
2 changes: 1 addition & 1 deletion django/contrib/auth/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,4 +533,4 @@ def test_bug_19349_render_with_none_value(self):

def test_readonly_field_has_changed(self):
field = ReadOnlyPasswordHashField()
self.assertFalse(field._has_changed('aaa', 'bbb'))
self.assertFalse(field.has_changed('aaa', 'bbb'))
2 changes: 1 addition & 1 deletion django/contrib/gis/forms/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def clean(self, value):

return geom

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
""" Compare geographic value of data with its initial value. """

try:
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/gis/tests/geoadmin/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_olwidget_has_changed(self):
"""
geoadmin = admin.site._registry[City]
form = geoadmin.get_changelist_form(None)()
has_changed = form.fields['point']._has_changed
has_changed = form.fields['point'].has_changed

initial = Point(13.4197458572965953, 52.5194108501149799, srid=4326)
data_same = "SRID=3857;POINT(1493879.2754093995 6894592.019687599)"
Expand Down
24 changes: 15 additions & 9 deletions django/forms/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from django.utils import formats
from django.utils.encoding import smart_text, force_str, force_text
from django.utils.ipv6 import clean_ipv6_address
from django.utils.deprecation import RemovedInDjango19Warning, RemovedInDjango20Warning
from django.utils.deprecation import RemovedInDjango19Warning, RemovedInDjango20Warning, RenameMethodsBase
from django.utils import six
from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit
from django.utils.translation import ugettext_lazy as _, ungettext_lazy
Expand All @@ -45,7 +45,13 @@
)


class Field(object):
class RenameFieldMethods(RenameMethodsBase):
renamed_methods = (
('_has_changed', 'has_changed', RemovedInDjango20Warning),
)


class Field(six.with_metaclass(RenameFieldMethods, object)):
widget = TextInput # Default widget to use when rendering this type of Field.
hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden".
default_validators = [] # Default set of validators
Expand Down Expand Up @@ -185,7 +191,7 @@ def get_limit_choices_to(self):
return self.limit_choices_to()
return self.limit_choices_to

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
"""
Return True if data differs from initial.
"""
Expand Down Expand Up @@ -629,7 +635,7 @@ def bound_data(self, data, initial):
return initial
return data

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
if data is None:
return False
return True
Expand Down Expand Up @@ -744,7 +750,7 @@ def validate(self, value):
if not value and self.required:
raise ValidationError(self.error_messages['required'], code='required')

def _has_changed(self, initial, data):
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':
Expand Down Expand Up @@ -779,7 +785,7 @@ def to_python(self, value):
def validate(self, value):
pass

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
# None (unknown) and False (No) are not the same
if initial is not None:
initial = bool(initial)
Expand Down Expand Up @@ -906,7 +912,7 @@ def validate(self, value):
params={'value': val},
)

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
if initial is None:
initial = []
if data is None:
Expand Down Expand Up @@ -1084,14 +1090,14 @@ def compress(self, data_list):
"""
raise NotImplementedError('Subclasses must implement this method.')

def _has_changed(self, initial, data):
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.widget.decompress(initial)
for field, initial, data in zip(self.fields, initial, data):
if field._has_changed(field.to_python(initial), data):
if field.has_changed(field.to_python(initial), data):
return True
return False

Expand Down
2 changes: 1 addition & 1 deletion django/forms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ def changed_data(self):
# Always assume data has changed if validation fails.
self._changed_data.append(name)
continue
if field._has_changed(initial_value, data_value):
if field.has_changed(initial_value, data_value):
self._changed_data.append(name)
return self._changed_data

Expand Down
6 changes: 3 additions & 3 deletions django/forms/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ def clean(self, value):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
return self.parent_instance

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
return False


Expand Down Expand Up @@ -1186,7 +1186,7 @@ def to_python(self, value):
def validate(self, value):
return Field.validate(self, value)

def _has_changed(self, initial, data):
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)
Expand Down Expand Up @@ -1254,7 +1254,7 @@ def prepare_value(self, value):
return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value]
return super(ModelMultipleChoiceField, self).prepare_value(value)

def _has_changed(self, initial, data):
def has_changed(self, initial, data):
if initial is None:
initial = []
if data is None:
Expand Down
3 changes: 3 additions & 0 deletions docs/internals/deprecation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ about each item can often be found in the release notes of two versions prior.

* Support for string ``view`` arguments to ``url()`` will be removed.

* The backward compatible shim to rename ``django.forms.Form._has_changed()``
to ``has_changed()`` will be removed.

.. _deprecation-removed-in-1.9:

1.9
Expand Down
4 changes: 3 additions & 1 deletion docs/ref/forms/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,9 @@ so that the comparison can be done:
>>> f.has_changed()

``has_changed()`` will be ``True`` if the data from ``request.POST`` differs
from what was provided in :attr:`~Form.initial` or ``False`` otherwise.
from what was provided in :attr:`~Form.initial` or ``False`` otherwise. The
result is computed by calling :meth:`Field.has_changed` for each field in the
form.

Accessing the fields from the form
----------------------------------
Expand Down
18 changes: 18 additions & 0 deletions docs/ref/forms/fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,24 @@ as the rendered output.
See the :ref:`format localization <format-localization>` documentation for
more information.


Checking if the field data has changed
--------------------------------------

``has_changed()``
~~~~~~~~~~~~~~~~~~

.. method:: Field.has_changed()

.. versionchanged:: 1.8

This method was renamed from ``_has_changed()``.

The ``has_changed()`` method is used to determine if the field value has changed
from the initial value. Returns ``True`` or ``False``.

See the :class:`Form.has_changed()` documentation for more information.

.. _built-in-fields:

Built-in ``Field`` classes
Expand Down
6 changes: 6 additions & 0 deletions docs/releases/1.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -676,3 +676,9 @@ An older (pre-1.0), more restrictive and verbose input format for the
Using the new syntax, this becomes::

``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``

``django.forms.Field._has_changed()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Rename this method to :meth:`~django.forms.Field.has_changed` by removing the
leading underscore. The old name will still work until Django 2.0.
10 changes: 5 additions & 5 deletions tests/forms_tests/tests/test_extra.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,19 +443,19 @@ def compress(self, data_list):
self.assertFormErrors(['This field is required.'], f.clean, ['some text', ['JP']])

# test with no initial data
self.assertTrue(f._has_changed(None, ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
self.assertTrue(f.has_changed(None, ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))

# test when the data is the same as initial
self.assertFalse(f._has_changed('some text,JP,2007-04-25 06:24:00',
self.assertFalse(f.has_changed('some text,JP,2007-04-25 06:24:00',
['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))

# test when the first widget's data has changed
self.assertTrue(f._has_changed('some text,JP,2007-04-25 06:24:00',
self.assertTrue(f.has_changed('some text,JP,2007-04-25 06:24:00',
['other text', ['J', 'P'], ['2007-04-25', '6:24:00']]))

# test when the last widget's data has changed. this ensures that it is not
# short circuiting while testing the widgets.
self.assertTrue(f._has_changed('some text,JP,2007-04-25 06:24:00',
self.assertTrue(f.has_changed('some text,JP,2007-04-25 06:24:00',
['some text', ['J', 'P'], ['2009-04-25', '11:44:00']]))

class ComplexFieldForm(Form):
Expand Down Expand Up @@ -803,7 +803,7 @@ def test_l10n(self):

def test_l10n_date_changed(self):
"""
Ensure that DateField._has_changed() with SelectDateWidget works
Ensure that DateField.has_changed() with SelectDateWidget works
correctly with a localized date format.
Refs #17165.
"""
Expand Down
Loading

0 comments on commit deed00c

Please sign in to comment.