Добавление ограничений моделей Django? - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть модель Период, как показано ниже:

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

Как добавить ограничения, чтобы Period.start_time < Period.end_time и модели Period имели такой порядок?

Период 1: 7: 00-7: 50; Период 2: 7: 50-8: 40; ...

Номер поля выражает порядок экземпляра периода. Мой подход заключается в добавлении методов, чтобы проверить, действительно ли это. Тем не менее, я хочу знать, что есть какой-либо способ для базы данных сделать это.

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Вы можете сделать это несколькими способами

Метод -1: Переопределить метод save() для модели Period как

<b>from django.core.exceptions import ValidationError</b>


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

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



Метод -2: Переопределить clean() метод модели

<b>from django.core.exceptions import ValidationError</b>


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

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


Метод - 3: Переопределить метод full_clean()

<b>from django.core.exceptions import ValidationError</b>


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

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



Ссылка
1. Model.clean () - Django doc
2. Model.save () - Django doc
3. Model.full_clean () - Django doc

0 голосов
/ 11 сентября 2018

Вместо «начала» и «конца» можно использовать «начало» и «продолжительность», используя DurationField , тогда из этого вычисляется свойство «конец».

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')) 
...