Как сравнить две даты в базе данных так, чтобы следующая начиналась с предыдущей?

У меня есть модель "Образование", где пользователь должен ввести годы обучения в университете. Поэтому я просто хочу, чтобы, когда пользователь добавляет год начала обучения, год окончания обучения не мог быть меньше года начала обучения и должен быть в пределах +10 лет от года начала обучения.

Сейчас мои модели выглядят так:

Мои модели:

def current_year():
    return datetime.date.today().year

def max_value_current_year(value):
    return MaxValueValidator(current_year())(value)

class Education(models.Model):
    name_university=models.CharField('University',max_length=300, blank=True)
    degree_of_edu=models.CharField('Degree of Education', max_length=25, blank=True)
    start_year=models.IntegerField('Start year',default=current_year(), validators=[MinValueValidator(1945), max_value_current_year])
    end_year=models.IntegerField('End year', default=current_year()+1,validators=[MinValueValidator(1945), MaxValueValidator(2100)])
    speciality=models.CharField('Speciality', default='Engineer', max_length=250, blank=True)

    def __str__(self):
        return '{}'.format(self.name_university)

Я понял, что IntegerFields не могут сравниваться друг с другом, потому что я уже получил ошибку, подобную этой:

'>' не поддерживается между экземплярами 'int' и 'IntegerField'

Так, например: если вы выбрали или написали: 2021, вы сможете выбрать конец обучения только 2022-2031

Или это вообще возможно сделать только на этапе формы?

Вы можете работать с clean() и фреймворком ограничений Django для обеспечения этого. Кроме того, вы допустили несколько ошибок относительно значения по умолчанию для годов: это должна быть ссылка на вызываемую переменную , а не на результат этой переменной, иначе, если ваш сервер будет работать между 31 декабря и 1 января, он вернет старый год.

from django.core.exceptions import ValidationError
from django.db.models import F, Q
from django.utils.timezone import now

def current_year():
    return now().year

def default_end_year():
    return current_year()+1

def max_value_current_year(value):
    if value > current_year():
        raise ValidationError('The year can not be greater than the current year.')

class Education(models.Model):
    # ⋮
    start_year=models.IntegerField(
        'Start year',
        default=current_year,
        validators=[MinValueValidator(1945), max_value_current_year]
    )
    end_year=models.IntegerField(
        'End year',
        default=default_end_year,
        validators=[MinValueValidator(1945), MaxValueValidator(2100)]
    )

    def clean(self, *args, **kwargs):
        if self.end_year < self.start_year:
            raise ValidationError('The end year can not be less than the start_year', code='end_year_too_low')
        if self.end_year > self.start_year+10:
            raise ValidationError('The end year should be at most ten years after the start year', code='study_too_long')
        return super().clean(*args, **kwargs)

    class Meta:
        constraints = [
            models.CheckConstraint(check=Q(end_year__gte=F('start_year')), name='end_year_too_low'),
            models.CheckConstraint(check=Q(end_year__lte=F('start_year')+10), name='study_too_long')
        ]

Метод constraints = [ … ] будет применять ограничения на уровне базы данных, если база данных поддерживает это. Метод .clean(…) [Django-doc] будет запущен, если вы используете ModelForm, или вы можете вручную очистить объект модели перед попыткой его сохранения.

Вернуться на верх