Validating a Django model field based on another field's value?

I dug around codebase of drf a little bit. You can get values of all fields using following approach, though it is not mentioned in docs. Doing so, you can throw serialization error as {'my_field':'error message} instead of {'non_field_error':'error message'}.

def validate_myfield(self, value):
   data = self.get_initial() # data for all the fields
   #do your validation

The validation per-field doesn't get sent any information about other fields, when it is defined like this:

def validate_myfield(self, value):
    ...

However, if you have a method defined like this:

def validate(self, data):
    ...

Then you get all the data in a dict, and you can do cross-field validation.


You can use the required package for your cross-field validation. It allows you to express your validation rules declaratively in python. You would have something like this with DRF:

class MySerializer(serializers.Serializer):

    REQUIREMENTS = (
        Requires("end_date", "start_date") +
        Requires("end_date", R("end_date") > R("start_date")) + 
        Requires("end_date", R("end_date") < today.date() + one_year) + 
        Requires("start_date", R("start_date") < today.date() + one_year)
     )

    start_date = serializers.DateField(required=False, null=True, blank=True)
    end_date = serializers.DateField(required=False, null=True, blank=True)

    def validate(self, data):
        self.REQUIREMENTS.validate(data)  # handle validation error

You could put the REQUIREMENTS on your Model and have both your DRF and Django Form validate your data using it.

Here is a blog post explaining more