Where should the validation of model fields go in django?
I could name at least two possible choices: in the overloaded .save() method of the model or in the .to_python() method of the models.Field subclass (obviously for that to work you must write custom fields).
Possible use cases:
- when it is absolutely neccessary to ensure, that an empty string doesn't get written into the database (blank=False keyword argument doesn't work here, it is for form validation only)
- when it is neccessary to ensure, that "choices" keyword argument gets respected on a db-level and not only in admin interface (kind of emulating a enum datatype)
There is also a class-level attribute empty_strings_allowed
in the models.Field base class definition and derived classes happily override it, however it doesn't seem to produce any effect on the database level, meaning I can still construct a model with empty-string fields and save it to the database. Which I want to avoid (yes, it is neccessary).
Possible implementations are
on the field level:
class CustomField(models.CharField):
__metaclass__ = models.SubfieldBase
def to_python(self, value):
if not value:
raise IntegrityError(_('Empty string not allowed'))
return models.CharField.to_python(self, value)
on the model level:
class MyModel(models.Model)
FIELD1_CHOICES = ['foo', 'bar', 'baz']
field1 = models.CharField(max_length=255,
choices=[(item,item) for item in FIELD1_CHOICES])
def save(self, force_insert=False, force_update=False):
if self.field1 not in MyModel.FIELD1_CHOICES:
raise IntegrityError(_('Invalid value of field1'))
# this can, of course, be made more generic
models.Model.save(self, force_insert, force_update)
Perhaps, I am missing something and this can be done easier (and cleaner)?