Commit ebb504db authored by Claude Paroz's avatar Claude Paroz
Browse files

Moved has_changed logic from widget to form field

Refs #16612. Thanks Aymeric Augustin for the suggestion.
parent ce27fb19
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -213,17 +213,6 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
        if value:
            return value.split(',')

    def _has_changed(self, initial, data):
        if initial is None:
            initial = []
        if data is None:
            data = []
        if len(initial) != len(data):
            return True
        for pk1, pk2 in zip(initial, data):
            if force_text(pk1) != force_text(pk2):
                return True
        return False

class RelatedFieldWidgetWrapper(forms.Widget):
    """
@@ -279,9 +268,6 @@ class RelatedFieldWidgetWrapper(forms.Widget):
    def value_from_datadict(self, data, files, name):
        return self.widget.value_from_datadict(data, files, name)

    def _has_changed(self, initial, data):
        return self.widget._has_changed(initial, data)

    def id_for_label(self, id_):
        return self.widget.id_for_label(id_)

+1 −23
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ from django.utils import six
from django.utils import translation

from django.contrib.gis.gdal import OGRException
from django.contrib.gis.geos import GEOSGeometry, GEOSException, fromstr
from django.contrib.gis.geos import GEOSGeometry, GEOSException

# Creating a template context that contains Django settings
# values needed by admin map templates.
@@ -117,25 +117,3 @@ class OpenLayersWidget(Textarea):
                    raise TypeError
                map_options[js_name] = value
        return map_options

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

        # Ensure we are dealing with a geographic object
        if isinstance(initial, six.string_types):
            try:
                initial = GEOSGeometry(initial)
            except (GEOSException, ValueError):
                initial = None

        # Only do a geographic comparison if both values are available
        if initial and data:
            data = fromstr(data)
            data.transform(initial.srid)
            # If the initial value was not added by the browser, the geometry
            # provided may be slightly different, the first time it is saved.
            # The comparison is done with a very low tolerance.
            return not initial.equals_exact(data, tolerance=0.000001)
        else:
            # Check for change of state of existence
            return bool(initial) != bool(data)
+25 −1
Original line number Diff line number Diff line
from __future__ import unicode_literals

from django import forms
from django.utils import six
from django.utils.translation import ugettext_lazy as _

# While this couples the geographic forms to the GEOS library,
# it decouples from database (by not importing SpatialBackend).
from django.contrib.gis.geos import GEOSException, GEOSGeometry
from django.contrib.gis.geos import GEOSException, GEOSGeometry, fromstr


class GeometryField(forms.Field):
    """
@@ -73,3 +75,25 @@ class GeometryField(forms.Field):
                    raise forms.ValidationError(self.error_messages['transform_error'])

        return geom

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

        # Ensure we are dealing with a geographic object
        if isinstance(initial, six.string_types):
            try:
                initial = GEOSGeometry(initial)
            except (GEOSException, ValueError):
                initial = None

        # Only do a geographic comparison if both values are available
        if initial and data:
            data = fromstr(data)
            data.transform(initial.srid)
            # If the initial value was not added by the browser, the geometry
            # provided may be slightly different, the first time it is saved.
            # The comparison is done with a very low tolerance.
            return not initial.equals_exact(data, tolerance=0.000001)
        else:
            # Check for change of state of existence
            return bool(initial) != bool(data)
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ class GeoAdminTest(TestCase):
        """ Check that changes are accurately noticed by OpenLayersWidget. """
        geoadmin = admin.site._registry[City]
        form = geoadmin.get_changelist_form(None)()
        has_changed = form.fields['point'].widget._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)"
+0 −8
Original line number Diff line number Diff line
@@ -135,11 +135,3 @@ class SelectDateWidget(Widget):
        s = Select(choices=choices)
        select_html = s.render(field % name, val, local_attrs)
        return select_html

    def _has_changed(self, initial, data):
        try:
            input_format = get_format('DATE_INPUT_FORMATS')[0]
            data = datetime_safe.datetime.strptime(data, input_format).date()
        except (TypeError, ValueError):
            pass
        return super(SelectDateWidget, self)._has_changed(initial, data)
Loading