[Django]-Adding Django models constraints?

3đź‘Ť

You can do it in several methods

Method -1: Override the save() method of Period model as

from django.core.exceptions import ValidationError


class Period(models.Model):
    number = models.PositiveIntegerField(primary_key=True)
    start_time = models.TimeField()
    end_time = models.TimeField()

    def save(self, *args, **kwargs):
        if self.end_time < self.start_time:
            raise ValidationError("some message")
        super().save(*args, **kwargs)

Method -2: Override the clean() method of model

from django.core.exceptions import ValidationError


class Period(models.Model):
    number = models.PositiveIntegerField(primary_key=True)
    start_time = models.TimeField()
    end_time = models.TimeField()

    def clean(self):
        super().clean()  # calling default cleaning
        if self.end_time < self.start_time:
            raise ValidationError("some message")

Method – 3: Override the full_clean() method

from django.core.exceptions import ValidationError


class Period(models.Model):
    number = models.PositiveIntegerField(primary_key=True)
    start_time = models.TimeField()
    end_time = models.TimeField()

    def full_clean(self, exclude=None, validate_unique=True):
        super().full_clean(exclude=None, validate_unique=True)  # calling default full_clean
        if self.end_time < self.start_time:
            raise ValidationError("some message")

Reference
1. Model.clean() – Django doc
2. Model.save() – Django doc
3. Model.full_clean() – Django doc

👤JPG

0đź‘Ť

Instead of having a “start” and “end” you could have a “start” and “duration” using the DurationField, then the “end” property is calculated from that.

class Period(models.Model):
      number = models.PositiveIntegerField(primary_key=True)
      start_time = models.TimeField()
      duration = models.DurationField()

      @property
      def end_time(self):
          return self.start_time + self.duration

You should also be able to use the end time in queries by adding it with the annotate method on a queryset, i.e.

query = Period.objects.all().annotate(end_time=F('start_time')+F('duration')) 
👤A. J. Parr

Leave a comment