Параметри Django DateField за замовчуванням


82

У мене є модель, яка має поле часу і дати:

date = models.DateField(_("Date"), default=datetime.now())

Коли я перевіряю додаток у вбудованому адміністраторі django, у нього DateFieldтакож є час, доданий до нього, так що при спробі зберегти його з'являється помилка. Як зробити за замовчуванням лише дату? ( datetime.today()також не працює)

Відповіді:


150

Ось чому ви повинні завжди імпортувати базовий datetimeмодуль:import datetime , а не datetimeклас в цьому модулі: from datetime import datetime.

Інша помилка, яку ви допустили, - це фактичний виклик функції за замовчуванням за допомогою (). Це означає, що всі моделі отримають дату в момент першого визначення класу - тому, якщо ваш сервер не працює протягом днів або тижнів без перезапуску Apache, всі елементи отримають однакову початкову дату.

Тож поле повинно бути:

import datetime
date = models.DateField(_("Date"), default=datetime.date.today)

Чи є спосіб зробити це, додавши дельту часу? Наприклад: default = datetime.date.today + datetime.timedelta (days = 4) ... цей код не працює, але це ідея. (Звичайно, метод збереження - це одне місце для цього, але просто цікаво, чи є спосіб зробити це як частина визначення)
Джо Дж.

1
@Joe J: це справді нове питання. Але той факт, що ви можете використовувати викликається, означає, що ви можете просто визначити власну функцію, яка повертає сьогодні + 4.
Даніель Роузман,

23
Що _("Date")робить?
benregn

10
@benregn Це поле надає мітку "Дата", але позначає його для перекладу за допомогою системи інтернаціоналізації.
Даніель Роузман,

Дякую за роз'яснення, я щойно запустив розробник Django, і мені було трохи незрозуміло, чи робив він більше, ніж просто маркування.
benregn

38

Ваша помилка - використання datetimeмодуля замість dateмодуля. Ви мали намір зробити це:

from datetime import date
date = models.DateField(_("Date"), default=date.today)

Якщо ви хочете зафіксувати лише поточну дату, правильний спосіб це зробити - використовувати auto_now_addпараметр:

date = models.DateField(_("Date"), auto_now_add=True)

Однак у документах fieldfield чітко зазначено, що auto_now_addі завждиauto_now буде використовуватися поточна дата, і не є типовим значенням, яке можна замінити.


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

5
DateTimeField не те саме. Якщо ви вказали datetime за замовчуванням для DateField, у вас будуть проблеми.
onekiloparsec

6

Я думаю, що кращим способом вирішити це було б використання дати-часу, що викликається:

from datetime import datetime

date = models.DateField(default=datetime.now)

Зверніть увагу, що дужки не використовувались. Якщо ви використовували дужки, ви б викликали now()функцію лише один раз (при створенні моделі). Натомість ви передаєте виклик як аргумент, таким чином, викликаючи його кожного разу, коли створюється екземпляр моделі.

Кредит Джанго Musings . Я цим користувався і чудово працює.


4

Це повинно зробити трюк:

models.DateTimeField(_("Date"), auto_now_add = True)

1
друже, я думаю, ти прочитав це неправильно. Питання стосується DateField, а не DateTimeField.
xxbinxx

2

Ви також можете використовувати lambda. Корисно, якщо ви використовуєте django.utils.timezone.now

date = models.DateField(_("Date"), default=lambda: now().date())

6
Подивіться документацію . Не добре використовувати Note that lambdas cannot be used for field options like default because they cannot be serialized by migrations. See that documentation for other caveats.
лямбду

@pulina ти маєш рацію, але в цьому випадку, коли потрібна дата, прив'язана до налаштованого часового поясу, це виглядає єдиним рішенням
oxfn

Ні. Ви можете вказати фактичну функцію в коді. Будь-яка посилання на функцію або метод відповідно до цього у зв’язку, що є функцією верхнього рівня моделі.
пуліна
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.