from django.db import models
from django.core.validators import MinValueValidator
class ExampleModel(models.Model):
MINIMUM_DURATION = 5
duration = models.IntegerField(validators=[MinValueValidator(MINIMUM_DURATION)], default=MINIMUM_DURATION)
Now, I declare a rest_framework 3.0 serializer for that model:
from rest_framework import serializers
class ExampleModelSerializer(serializers.ModelSerializer):
class Meta:
model = ExampleModel
ExampleModelSerializer will enforce that any given input for the duration field is, in fact, >= MINIMUM_DURATION. However, as written above, the model itself will not enforce the minimum value for duration. Someone on the backend could save an ExampleModel instance with a duration equal to 1 without error. I decide I dislike this behavior, and adjust my model so that the model enforces the validation on its own:
class ExampleModel(models.Model):
MINIMUM_DURATION = 5
duration = models.IntegerField(validators=[MinValueValidator(MINIMUM_DURATION)], default=MINIMUM_DURATION)
def save(self, *args, **kwargs):
self.full_clean()
super(ExampleModel, self).save(*args, **kwargs)
Now, as far as I'm aware, if I use ExampleModelSeriailzer to create a new ExampleModel instance (say, through a public API), I'll run the validation on the duration field twice: the serializer will run the validation on the input, and then full_clean() will duplicate the validation when the model is saved.
Rest framework specific question: is there some way I can get around duplicating these validation checks?
High level question: should I not be enforcing MinValueValidation at the model level at all (i.e. should I allow the database to contain values that are less than MINIMUM_DURATION)? I feel like it's a no brainer to enforce my simple constraint (of duration >=5) at the database level to keep my data in a "clean"/expected state, but the fact that I'm duplicating validation logic whenever I instantiate a model using the serializer makes me feel like I'm doing something wrong.