Замороженный день в форме Django

Я использую django, nginx, gunicorn. Помогите пожалуйста, форма записывает дату создания записи. Долгое время все работало нормально, но недавно дата зафиксировалась на 2024-10-07, хотя была 2024-10-09. Время на сервере правильное. Перезапуск gunicorn помог, но теперь он записывает 2024-10-09. Можете ли вы указать причину сбоя?

class MyForm(forms.ModelForm):
    create_date = forms.DateField(input_formats=['%Y-%m-%d'],
                                  widget=forms.DateInput(attrs={'type': 'date', 'value': (datetime.today() + timedelta(hours=3)).strftime('%Y-%m-%d'), 'readonly': True}),
                                  label='Create date')
    product_cost = forms.IntegerField(label='Cost')

Объяснение проблемы

Проблема заключается в этой части строки:

'value': (datetime.today() + timedelta(hours=3)).strftime('%Y-%m-%d')

Выражение, которое вы использовали для атрибута value, оценивается во время создания класса формы, то есть при первом импорте формы, и, скорее всего, при запуске приложения. Как вы сказали, когда вы перезапустили приложение 2024-10-09, значение было заморожено на этой дате и не изменится, пока вы не перезапустите приложение снова.

Решение

Вы должны установить значение динамически при инициализации формы (если вы хотите отобразить значение в форме на сайте) или во время сохранения формы, если вы хотите установить только текущую дату в модели.

Случай #1 - при инициализации:

class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
    
         create_date = (datetime.today() + timedelta(hours=3)).strftime('%Y-%m-%d')
         self.fields["create_date"].widget.attrs["value"] = create_date

Случай #2 - при сохранении:

class MyForm(forms.ModelForm):
    def save(self, *args, **kwargs):
         instance = super().save(*args, **kwargs)
    
         create_date = (datetime.today() + timedelta(hours=3)).strftime('%Y-%m-%d')
         instance.create_date = create_date
         instance.save()
         return instance

Альтернативное решение

Если ваша цель состоит в том, чтобы create_date автоматически устанавливался для экземпляра модели, вы можете установить параметр default для поля модели в вызываемую переменную. Что-то вроде этого:

def auto_create_date():
    return datetime.today() + timedelta(hours=3)

class MyModel(models.Model):
    create_date = models.DateField(default=auto_create_date)

Используя вышеизложенное, вам не нужно поле в вашей форме.

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