Автоматична дата створення об'єктів моделі Django?


153

Який найкращий спосіб автоматично встановити дату створення об’єкта, а також поле, яке буде записано, коли об’єкт востаннє оновлений?

models.py:

created_at = models.DateTimeField(False, True, editable=False)
updated_at = models.DateTimeField(True, True, editable=False)

views.py:

if request.method == 'POST':
    form = MyForm(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        return HttpResponseRedirect('obj_list')

Я отримую помилку:

objects_object.created_at may not be NULL

Чи потрібно мені вручну встановлювати це значення? Я подумав, що це був пункт про передані параметри DateTimeField(або вони просто за замовчуванням, і оскільки я встановив, editable=Falseвони не відображаються у формі, отже, не надсилаються у запиті, а тому не отримують поставити у форму?).

Який найкращий спосіб зробити це? __init__Метод?

Відповіді:


312

Ви можете використовувати auto_nowі auto_now_addпараметри, updated_atі created_atвідповідно.

class MyModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

31
auto_nowі auto_now_addвважаються злими, тому намагайтеся уникати їх. Ця відповідь пояснює, чому і забезпечує кращий підхід, перекриваючи save()метод.
грегольцов

3
це призводить до цієї помилки:You are trying to add a non-nullable field 'created_at' to gameuser without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows) 2) Quit, and let me add a default in models.py Select an option: 1 Please enter the default value now, as valid Python The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now() >>> timezone.now()
Kaleem Ullah

1
видаліть рядки на базі даних або перевірте варіант 1 і додайте timezone.now ()
mullerivan


1
Я думаю, що коментар @ gregoltsov застарілий на даний момент. Використання auto_now_addабо auto_nowпрацює просто чудово. Він встановлює поле перед збереженням моделі ( github.com/django/django/blob/stable/3.0.x/django/db/models/… ).
yndolok

26

Ну, наведена вище відповідь правильна, auto_now_add і auto_now це зробили б, але краще було б зробити абстрактний клас і використовувати його в будь-якій моделі, де вам потрібні created_atі updated_atполя.

class TimeStampMixin(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

Тепер, де ви хочете його використовувати, ви можете зробити просту спадщину, і ви можете використовувати часову позначку в будь-якій моделі, що вам подобається.

class Posts(TimeStampMixin):
    name = models.CharField(max_length=50)
    ...
    ...

Таким чином, ви можете використовувати об'єктно-орієнтовану повторну використання в Django DRY (не повторюйте себе)

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