Opened 13 years ago

Closed 12 years ago

#15271 closed Bug (fixed)

django.contrib.gis.forms.fields.GeometryField should call to_python before cleaning

Reported by: Daniel Barreto Owned by: nobody
Component: GIS Version: dev
Severity: Normal Keywords: gis, field, clean, to_python
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

GeometryField overrides the default clean method for Field class and doesn't take in account the call to to_python before cleaning of the value.
This is important because when using GeometryFields in a form you could want to render it with a MultiWidget, for example:

Let's say we create a PointField (which inherits from GeometryField) with a MultiWidget that renders to FloatFields (one for each coordinate). This widget will return a list with both float values as its value, and that's what will be passed to the clean method. On every other field, we know that this list will be passed to to_python before calling clean, but with GeometryField that's not the case.

Following that example, you could redefine the to_python method in our new PointField class to check if the value is instance of a tuple/list (like it's done in a DateTimeField), and transform it to a string representing the Point WKT formed with the two values of that list, but you will also have to redefine clean method to call to_python first and then do the cleaning.

I'm submitting a simple patch to fix this.

Attachments (3)

0001-Added-to_python-to-GeometryField-which-transform-the.patch (1.8 KB ) - added by Daniel Barreto 13 years ago.
0001-Tests-for-GeometryField.to_python-method.patch (2.1 KB ) - added by Daniel Barreto 13 years ago.
15271.diff (2.8 KB ) - added by Colin Copeland 12 years ago.

Download all attachments as: .zip

Change History (10)

comment:1 by Russell Keith-Magee, 13 years ago

Needs tests: set
Triage Stage: UnreviewedAccepted

comment:2 by Daniel Barreto, 13 years ago

just added a patch for the new method tests. I don't know if more tests are required, I think they're pretty much covered by the clean method tests.

comment:3 by Łukasz Rekucki, 13 years ago

Severity: Normal
Type: Bug

comment:4 by Colin Copeland, 12 years ago

Easy pickings: unset
Owner: changed from nobody to Colin Copeland
Status: newassigned
UI/UX: unset

comment:5 by Colin Copeland, 12 years ago

To illustrate volrath's suggested changes, the provided patch would allow you to do something along the lines of this:

from django import forms
from django.contrib.gis.forms import GeometryField


class CoordsWidget(forms.MultiWidget):

    def __init__(self, *args, **kwargs):
        widgets = (forms.TextInput(), forms.TextInput())
        super(CoordsWidget, self).__init__(widgets, *args, **kwargs)

    def decompress(self, value):
        return value.coords


class CoordsField(GeometryField):
    widget = CoordsWidget

    def to_python(self, value):
        wkt = "POINT({0} {1})".format(value[0], value[1])
        return super(CoordsField, self).to_python(wkt)


class LocationForm(forms.ModelForm):

    point = CoordsField()

    class Meta(object):
        model = Location

I'll consolidate the separate patches into a single file.

Last edited 12 years ago by Colin Copeland (previous) (diff)

by Colin Copeland, 12 years ago

Attachment: 15271.diff added

comment:6 by Colin Copeland, 12 years ago

Owner: changed from Colin Copeland to nobody
Status: assignednew

I reviewed volrath's patches and consolidated them into a single file. I also created a pull request here:

https://github.com/django/django/pull/78

comment:7 by Claude Paroz <claude@…>, 12 years ago

Resolution: fixed
Status: newclosed

In [41eb70f7620dbae43bb72f265489fa3ac19c5c66]:

Fixed #15271 -- Defined a to_python method for GeometryField

Thanks volrath and copelco for their work on the patch.

Note: See TracTickets for help on using tickets.
Back to Top