添加Django模型约束?

时间:2018-09-11 04:07:55

标签: python django django-models

我的周期模型如下:

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

如何添加约束以使Period.start_time < Period.end_time和期间模型具有这样的顺序?

  

时段1:7:00-7:50;期间2:7:50-8:40; ...

字段编号表示期间实例的顺序。我的方法是添加方法以检查其是否有效。但是,我想知道有任何数据库方法可以做到这一点。

2 个答案:

答案 0 :(得分:2)

您可以通过多种方法进行操作

方法-1:

替代save()模型的 Period 方法
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)



方法-2:覆盖模型的 clean() 方法

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")


方法-3:覆盖 full_clean() 方法

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")



参考
1. Model.clean() - Django doc
2. Model.save() - Django doc
3. Model.full_clean() - Django doc

答案 1 :(得分:0)

使用DurationField可以拥有一个“开始”和“持续时间”,而不是具有一个“开始”和“结束”,然后从中计算出“ end”属性。

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

通过在查询集上将annotate方法添加到结束时间,即

,您还应该能够在查询中使用结束时间。
query = Period.objects.all().annotate(end_time=F('start_time')+F('duration'))