Проблемы с datetime в Django (по умолчанию = datetime.now ())

У меня такая модель db:

from datetime import datetime class TermPayment(models.Model): # cut out some fields, non relevant to the question date = models.DateTimeField(default=datetime.now(), blank=True) 

И когда добавляется новый экземпляр:

 tp = TermPayment.objects.create(**kwargs) 

У меня проблема: все записи в базе данных имеют одинаковое значение в поле даты – дату первого платежа. После перезапуска сервера – одна запись имеет новую дату, а другие – то же, что и первая. Похоже, что используется кеш данных, но я не могу найти где.

база данных: mysql 5.1.25

django v1.1.1

8 Solutions collect form web for “Проблемы с datetime в Django (по умолчанию = datetime.now ())”

похоже, что datetime.now() оценивается, когда модель определена, а не каждый раз, когда вы добавляете запись.

У Django есть функция, чтобы выполнить то, что вы пытаетесь сделать уже:

 date = models.DateTimeField(auto_now_add=True, blank=True) 

или

 date = models.DateTimeField(default=datetime.now, blank=True) 

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

Дополнительная информация доступна в справочной системе модели Django

Вместо использования datetime.now вы должны действительно использовать from django.utils.timezone import now

Справка:

  • Документация для django.utils.timezone.now

Из документации по умолчанию по умолчанию для модели django:

Значение по умолчанию для поля. Это может быть значение или вызываемый объект. Если он вызывается, он будет вызываться каждый раз при создании нового объекта.

Поэтому последующие должны работать:

 date = models.DateTimeField(default=datetime.now,blank=True) 

Значение datetime.now() оценивается при создании класса, а не при добавлении новой записи в базу данных.

Чтобы достичь того, что вы хотите, определите это поле как:

 date = models.DateTimeField(auto_now_add=True) 

Таким образом, поле date будет установлено на текущую дату для каждой новой записи.

У Давида был правильный ответ. Скобка () делает ее так, что вызываемый timezone.now () вызывается каждый раз, когда модель оценивается. Если вы удалите () из timezone.now () (или datetime.now (), если используете объект наивного datetime), чтобы сделать это именно так:

 default=timezone.now 

Затем он будет работать так, как вы ожидаете:
Новые объекты получат текущую дату, когда они будут созданы, но дата не будет переопределяться каждый раз, когда вы делаете manage.py makemigrations / migrate.

Я просто столкнулся с этим. Огромное спасибо Дэвиду.

Ответ на этот вопрос на самом деле ошибочен.

Автоматическое заполнение значения (auto_now / auto_now_add не совпадает с по умолчанию). Значением по умолчанию будет то, что пользователь видит, если это новый объект. То, что я обычно делаю, это:

 date = models.DateTimeField(default=datetime.now, editable=False,) 

Убедитесь, что если вы пытаетесь представить это на странице администратора, вы указываете его как «read_only» и ссылаетесь на имя поля

 read_only = 'date' 

Опять же, я делаю это, так как мое значение по умолчанию обычно не редактируется, а страницы-администраторы игнорируют не-редактируемые данные, если не указано иное. Однако существует определенная разница между установкой значения по умолчанию и внедрением auto_add, который является ключевым здесь. Проверьте это!

datetime.now() оценивается один раз, когда ваш экземпляр создается. Попробуйте удалить круглые скобки, чтобы возвращалась функция datetime.now и THEN. У меня была такая же проблема с установкой значений по умолчанию для моего DateTimeField и написала мое решение здесь .

Из справочника языка Python в разделе « Определения функций» :

Значения параметров по умолчанию оцениваются при выполнении определения функции. Это означает, что выражение оценивается один раз, когда функция определена, и что для каждого вызова используется то же самое «предварительно вычисленное» значение.

К счастью, у Django есть способ сделать то, что вы хотите, если вы используете аргумент auto_now для DateTimeField :

 date = models.DateTimeField(auto_now=True) 

См. Документы Django для DateTimeField .

  • Несколько ModelAdmins / views для той же модели в Django admin
  • Межплатформенный интерфейс для virtualenv
  • Django virtualenv layout
  • Сжатие отношений «один ко многим» в Django
  • Кажется, что Django кэширует datetime.now ()
  • Шаблон Django: включить перевод с переменной
  • Django 1.7.1: детская модель, удалите все ссылки на родительскую модель и сделайте дочернюю модель наследованием от дедушки вместо
  • Сценарий haystack elasticsearch RealtimeSignalProcessor обновляет только соединение по умолчанию
  • Python - лучший язык программирования в мире.