'Prevent DateRangeField overlap in Django model?

Now that Django supports the DateRangeField, is there a 'Pythonic' way to prevent records from having overlapping date ranges?

Hypothetical use case

One hypothetical use case would be a booking system, where you don't want people to book the same resource at the same time.

Hypothetical example code

class Booking(models.model):
    # The resource to be reserved
    resource = models.ForeignKey('Resource')
    # When to reserve the resource
    date_range = models.DateRangeField()

    class Meta:
        unique_together = ('resource', 'date_range',)


Solution 1:[1]

You can check this in your model full_clean method, which is called automatically during ModelForm validation. It is NOT called automatically if you directly save the object.. this is a known problem with Django validation that you may be aware of already! So if you want validation any time the object is saved, you have to also override the model save method.

class Booking(models.model):

    def full_clean(self, *args, **kwargs):
        super(Booking, self).full_clean(*args, **kwargs)

        o = Booking.objects.filter(date_range__overlap=self.date_range).exclude(pk=self.pk).first()
        if o:
            raise forms.ValidationError('Date Range overlaps with "%s"' % o)

    # do not need to do this if you are only saving the object via a ModelForm, since the ModelForm calls FullClean.
    def save(self):
        self.full_clean()
        super(Booking, self).save()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 little_birdie