Adding extra constraints into fields in Django

I would not put constraints like these in the save method, it's too late. Raising an exception there, doesn't help the user who entered the data in the wrong way, because it will end up as a 500 and the user won't get the form with errors back etc.

You should really check for this in the Forms/ModelForms clean method and raise a ValidationError, so form.is_valid() returns false and you can send the errors in the form back to the user for correction.

Also note that since version 1.2, Django has had Model Validation.

It would look something like this:

class Foo(models.Model):
    #  ... model stuff...
    def clean(self):
        if self.start_date > self.end_date:
            raise ValidationError('Start date is after end date')

As of Django 2.2, database level constraints are supported:

from django.db import models
from django.db.models import CheckConstraint, Q, F

class Event(models.Model):
    start_date = models.DatetimeField() 
    end_date = models.DatetimeField()

    class Meta:
        constraints = [
            CheckConstraint(
                check = Q(end_date__gt=F('start_date')), 
                name = 'check_start_date',
            ),
        ]

Do it inside your save method of your model:

def save(self, *args, **kwargs):
    if(self.end_date > self.start_date):
        super(Foo, self).save(*args, **kwargs)
    else:
        raise Exception, "end_date should be greater than start_date"