id,summary,reporter,owner,description,type,status,component,version,severity,resolution,keywords,cc,stage,has_patch,needs_docs,needs_tests,needs_better_patch,easy,ui_ux
16110,GeometryField does not allow setting blank=True and null=False,slinkp,nobody,"Sometimes you want to populate a required field's missing value with a value generated eg. from other form fields.
One common idiom for doing this is to have SomeField(blank=True, null=False) and provide the missing value in eg. the Form's clean() method.
For example, I've done variations on this a lot:
{{{
class Foo(Model):
geom = PointField(blank=True, null=False)
address = CharField(max_length=100)
class Meta:
app_label = 'myblock' # or whatever,
class FooForm(ModelForm):
class Meta:
model = Foo
def clean(self):
geom = self.cleaned_data.get('geom')
if not geom:
self.cleaned_data['geom'] = geocode(self.cleaned_data['address'])
return super(FooForm, self).clean()
}}}
But with a GeometryField, that doesn't work, because of these lines in
GeometryField.clean() in django/contrib/gis/forms/fields.py :
{{{
if not value:
if self.null and not self.required:
# The geometry column allows NULL and is not required.
return None
else:
raise forms.ValidationError(self.error_messages['no_geom'])
}}}
Effectively, this makes blank=True meaningless.
As far as I know, GeometryField is the only FormField shipped with django that behaves this way.
This is surprising and inconsistent, and leads to odd workarounds to convince forms.GeometryField to leave you alone. Eg. hacking a ModelAdmin's formfield_for_dbfield() like so:
{{{
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'geom':
kwargs['required'] = False
kwargs['null'] = True
return super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)
}}}
Fixing this is trivial. Patch attached.",Bug,closed,GIS,master,Normal,fixed,,,Accepted,1,0,0,0,0,0