Решение ошибки Django: 'created' не может быть null
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Параметр auto_now_add
в моделях Django устанавливает время и дату создания записи при её первоначальном сохранении. А параметр auto_now
обновляет время и дату каждый раз при сохранении записи, отражая момент последнего её изменения.
Пример:
class MyModel(models.Model):
initial_timestamp = models.DateTimeField(auto_now_add=True)
latest_timestamp = models.DateTimeField(auto_now=True)
В данном контексте поле initial_timestamp
будет содержать время создания объекта, а latest_timestamp
— время его последнего сохранения.
Ваш собственный метод сохранения: контроль временных меток
Удобство использования auto_now
и auto_now_add
несет в себе некоторые ограничения. В Django вы можете воспользоваться более гибким решением, переопределив метод save()
.
Пример пользовательского метода сохранения:
from django.utils import timezone
class MyModel(models.Model):
initial_timestamp = models.DateTimeField(editable=False)
latest_timestamp = models.DateTimeField(editable=False)
def save(self, *args, **kwargs):
if not self.pk: # создаём запись?
self.initial_timestamp = timezone.now()
self.latest_timestamp = timezone.now() # обновляем при каждом сохранении
super().save(*args, **kwargs)
Этот метод позволит установить initial_timestamp
один раз при создании объекта и обновлять latest_timestamp
при каждом его сохранении. Опция editable=False
спрячет поля из административного интерфейса, предотвращая безразрешительное редактирование.
Запутываемость auto_now и auto_now_add
Хотя эти опции могут показаться удобными, при определённых обстоятельствах они могут создать неприятности из-за тесной связи с механизмами базы данных и настройками по умолчанию. Они делают поля невозможными для редактирования в административном интерфейсе, что может быть нежелательным.
Лучше воспользоваться функцией по умолчанию, например timezone.now
, которая динамична и рассматривает часовой пояс сервера.
Оптимизация работы с DateTime
Чтобы более эффективно работать с датой и временем в Django, рекомендуем:
- Создать собственный тип поля или использовать
AutoDateTimeField
. - Вместо значения
default
установитьtimezone.now
(без вызова функции) с тем чтобы гарантировать динамичность метки. - Изучать ошибки Django, такие как #7634 и #12785, чтобы быть в курсе ограничений
auto_now
иauto_now_add
. - Воспользоваться
readonly_fields
в административной панели Django, чтобы можно было показывать временные метки без возможности их редактирования.
Дайте больше власти пользователю!
Django предоставляет разработчику свободу выбора управления временными метками через auto_now
, auto_now_add
или путём переопределения метода save()
. Важно, чтобы поля DateTime соответствовали требованиям вашего приложения, учитывая миграции и необходимость значения NOT NULL для соответствующих полей.
Визуализация
Представим auto_now
и auto_now_add
как стражей времени:
Когда запись приближается к воротам базы данных:
| Параметр поля | Задача стража | Символ |
| ---------------- | --------------------------------------------------- | ---------- |
| `auto_now_add` | Отметить дату первого прибытия (однократно) | 📆⚔️ |
| `auto_now` | Обновлять дату последнего посещения (при каждом сохранении) | 🔄🛡️ |
auto_now_add
оставляет отметку даты первого сохранения:
# Дата первого сохранения
record.initial_timestamp = "2023-04-01"; # 📆⚔️ Однократная отметка
А auto_now
слежит за каждым сохранением:
# При каждом сохранении:
record.latest_timestamp = "2023-04-02"; # 🔄🛡️ Зафиксировано каждое обновление
Такая система обеспечивает точное отслеживание всех изменений записи.