Opened 14 years ago
Closed 13 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)
Change History (10)
by , 14 years ago
Attachment: | 0001-Added-to_python-to-GeometryField-which-transform-the.patch added |
---|
comment:1 by , 14 years ago
Needs tests: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
by , 14 years ago
Attachment: | 0001-Tests-for-GeometryField.to_python-method.patch added |
---|
comment:2 by , 14 years ago
comment:3 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → Bug |
comment:4 by , 13 years ago
Easy pickings: | unset |
---|---|
Owner: | changed from | to
Status: | new → assigned |
UI/UX: | unset |
comment:5 by , 13 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
by , 13 years ago
Attachment: | 15271.diff added |
---|
comment:6 by , 13 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
I reviewed volrath's patches and consolidated them into a single file. I also created a pull request here:
comment:7 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
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.