priestc
priestc

Reputation: 35170

Custom validation of a ModelField in Django

my model looks like this:

class MyModel(models.Model):
    field1 = models.FloatField(default=0)
    field2 = models.FloatField(default=0)

This is how it behaves:

>>> m = MyModel()
>>> m.full_clean()

>>> m = MyModel(field1=8.9)
>>> m.full_clean()

>>> m = MyModel(field1='')
>>> m.full_clean()
ValidationError: {'field1': [u'This value must be a float.'], ...

I want it to accept blank strings and have it use 0. I also want it to accept values such as "5:56" and have it use "5.93333". (I already have a function that can do this)

Currently I have this working with a custom form field (and it's ugly as sin), but I want to move it all to use model validation. Whats the best way to go about this?

Upvotes: 1

Views: 748

Answers (1)

eruciform
eruciform

Reputation: 7736

Make a clean_field1 function in your form and verify it in there. Throw a validation error if it's improper, and reformat and return the "proper" value if it is. Example:

http://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-a-specific-field-attribute

Update:

Question clarified: user wants a Model Field that does this.

Override FloatField and the get_prep_value and to_python routines within:

class MagicalFloatField(FloatField):
  def to_python( self, value_from_db ):
    ...
    return what_should_go_into_model_field_value
  def get_prep_value( self, value_from_field ):
    ...
    return what_should_go_into_db

So you can do the "5:26" <--> "5.26" there. Then use your field in your model:

class MagicalModel(Model):
  foo = MagicalFloatField()

Reference:

http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#django.db.models.to_python

Also, for an example of what it expects and how to raise validation errors, look at what you're subclassing -- look up FloatField in site-packages/django/db/models/fields/__init__.py

Upvotes: 1

Related Questions