Для Джанго 1.1.
У меня есть это в моем models.py:
class User(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
При обновлении строки я получаю:
[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error] return self.cursor.execute(query, args)
Соответствующая часть моей базы данных:
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
Это повод для беспокойства?
Дополнительный вопрос: в моем админ-инструменте эти два поля не отображаются. Это ожидается?
python
django
datetime
django-models
django-admin
Пол Тарьян
источник
источник
update()
метод не будет вызываться,save()
что означает, что он не может обновитьmodified
поле автоматическиОтветы:
Любое поле с установленным
auto_now
атрибутом также будет наследоватьсяeditable=False
и, следовательно, не будет отображаться в панели администратора. В прошлом были разговоры о том, чтобы аргументыauto_now
иauto_now_add
исчезли, и, хотя они все еще существуют, я чувствую, что вам лучше использовать собственныйsave()
метод .Поэтому для правильной работы я бы рекомендовал не использовать
auto_now
илиauto_now_add
вместо этого определять собственныйsave()
метод, чтобы убедиться, чтоcreated
он обновляется только в том случае, еслиid
он не установлен (например, при первом создании элемента), и обновлять егоmodified
каждый раз, когда элемент сохраняетсяЯ проделал то же самое с другими проектами, написанными мной с использованием Django, и вы
save()
выглядите так:Надеюсь это поможет!
Редактировать в ответ на комментарии:
Причина, по которой я просто придерживаюсь перегрузки по
save()
сравнению с этими аргументами поля, имеет две причины :django.utils.timezone.now()
противdatetime.datetime.now()
, потому что он будет возвращать TZ-осведомленный или наивныйdatetime.datetime
объект в зависимости отsettings.USE_TZ
.Чтобы выяснить, почему ОП увидел ошибку, я точно не знаю, но похоже, что
created
она даже не заполняется вообще, несмотря на то, что имеетauto_now_add=True
. Для меня это выделяется как ошибка, и подчеркивает пункт # 1 в моем маленьком списке выше:auto_now
иauto_now_add
в лучшем случае ненадежен.источник
save()
для каждой из моих моделей намного сложнее, чем использованиеauto_now
(так как мне нравятся эти поля на всех моих моделях). Почему эти параметры не работают?Но я хотел бы отметить, что мнение, выраженное в принятом ответе , несколько устарело. Согласно последним обсуждениям (ошибки django # 7634 и # 12785 ), auto_now и auto_now_add никуда не денутся, и даже если вы перейдете к исходному обсуждению , вы найдете сильные аргументы против RY (как в DRY) в пользовательском сохранении методы.
Было предложено лучшее решение (пользовательские типы полей), но оно не набрало достаточного импульса, чтобы превратить его в django. Вы можете написать свой в три строки (это предложение Джейкоба Каплана-Мосса ).
источник
Говоря о дополнительном вопросе: если вы хотите видеть эти поля в админке (хотя вы не сможете их редактировать), вы можете добавить их
readonly_fields
в свой класс админки.Ну, это относится только к последним версиям Django (я думаю, 1.3 и выше)
источник
XxAdmin
классу. Я прочитал его слишком быстро и попытался добавить его в свои классыAdminForm
илиModelForm
классы, и понятия не имел, почему они не рендерили «поля только для чтения». Кстати, есть ли возможность иметь настоящие «поля только для чтения» в форме?Я думаю, что самое простое (и, возможно, самое элегантное) решение здесь - это использовать тот факт, что вы можете установить
default
вызываемый. Итак, чтобы обойти специальную обработку администратора auto_now, вы можете просто объявить поле следующим образом:Важно, чтобы вы не использовали его,
timezone.now()
поскольку значение по умолчанию не будет обновляться (то есть значение по умолчанию устанавливается только при загрузке кода). Если вы обнаружите, что делаете это много, вы можете создать собственное поле. Тем не менее, это уже довольно СУХОЙ, я думаю.источник
makemigrations
он интерпретирует значение по умолчанию как время, когда вы запускаетеmakemigrations
, и поэтому считает, что значение по умолчанию изменилось!default=timezone.now()
а не то, что рекомендуется:default=timezine.now
(без скобок)?Если вы измените свой класс модели следующим образом:
Тогда это поле появится на моей странице смены администратора.
источник
python manage.py makemigrations
: KeyError: u'editable 'На основании того, что я прочитал, и моего опыта работы с Django, auto_now_add содержит ошибки. Я согласен с jthanism --- отвергни нормальный метод сохранения, он чистый, и ты знаешь, что происходит. Теперь, чтобы сделать его сухим, создайте абстрактную модель с именем TimeStamped:
И затем, когда вы хотите модель, которая имеет такое поведение с отметкой времени, просто подкласс:
Если вы хотите, чтобы поля отображались в админке, просто удалите
editable=False
опциюисточник
timezone.now()
вы используете здесь? Я предполагаюdjango.utils.timezone.now()
, но я не уверен. Кроме того, зачем использовать,timezone.now()
а неdatetime.datetime.now()
?timezone.now()
заключается в том, что он осведомлен о часовом поясе, тогдаdatetime.datetime.now()
как часовой пояс наивен. Вы можете прочитать об этом здесь: docs.djangoproject.com/en/dev/topics/i18n/timezonesdefault=timezone.now
в конструкторе полей?update_fields
указан аргумент arg, а «last_modified» нет в списке, я бы добавил:if 'update_fields' in kwargs and 'last_modifed' not in kwargs['update_fields']: kwargs['update_fields'].append('last_modified')
Нет, Django автоматически добавляет его для вас при сохранении моделей, так что это ожидаемо.
Поскольку эти поля добавляются автоматически, они не отображаются.
В дополнение к вышесказанному, как сказал synack, в списке рассылки django была дискуссия, чтобы убрать это, потому что он «не очень хорошо продуман» и является «хаком»
Очевидно, вам не нужно писать это для каждой модели. Вы можете написать это для одной модели и наследовать от нее другие.
Но, как
auto_add
иauto_now_add
там, я бы использовал их, а не пытаться написать метод сам.источник
Мне нужно что-то подобное сегодня на работе. Значение по умолчанию должно быть
timezone.now()
, но редактируемое как в представлениях администратора, так и в представлениях классов, унаследованных отFormMixin
, поэтому для созданного в моемmodels.py
коде ниже выполняются эти требования:Для
DateTimeField
, я думаю , удалить.date()
из функции и измененийdatetime.date
кdatetime.datetime
или лучшеtimezone.datetime
. Я не пробовал с этимDateTime
, только сDate
.источник
Вы можете использовать
timezone.now()
для созданного иauto_now
для измененного:Если вы используете пользовательский первичный ключ вместо по умолчанию
auto- increment int
,auto_now_add
это приведет к ошибке.Вот код Django по умолчанию DateTimeField.pre_save с
auto_now
иauto_now_add
:Я не уверен, что это за параметр
add
. Я надеюсь, что это будет что-то вроде:источник
Что касается вашего дисплея администратора, см. Этот ответ .
Примечание:
auto_now
иauto_now_add
установленыeditable=False
по умолчанию, поэтому это применимо.источник
auto_now=True
не работал для меня в Django 1.4.1, но приведенный ниже код спас меня. Это для часовых поясов с учетом даты и времени.источник
Здесь мы создали и обновили столбцы, которые будут иметь метку времени при создании и когда кто-то изменяет обратную связь.
auto_now_add будет устанавливать время при создании экземпляра, тогда как auto_now будет устанавливать время, когда кто-то изменил его отзыв.
источник
Вот ответ, если вы используете юг и хотите по умолчанию указать дату добавления поля в базу данных:
Затем выберите вариант 2 : datetime.datetime.now ()
Выглядит так:
источник