Django auto_now и auto_now_add

Некоторые проекты GNOME мигрировали на waf.

Это основано на Python, как Scons, но также и автономно - так, а не потребуйте, чтобы у других разработчиков был Ваш любимый установленный инструмент сборки, Вы просто копируете автономный сценарий сборки в свой проект.

249
задан Peter Mortensen 30 September 2014 в 16:01
поделиться

3 ответа

Любое поле с установленным атрибутом auto_now также унаследует editable = False и поэтому не будет отображаться в панели администратора. В прошлом были разговоры о том, чтобы убрать аргументы auto_now и auto_now_add , и, хотя они все еще существуют, я считаю, что вам лучше просто использовать пользовательский save () метод .

Итак, чтобы все работало правильно, я бы рекомендовал не использовать auto_now или auto_now_add и вместо этого определить свой собственный save () , чтобы убедиться, что created обновляется, только если id не установлен (например, при первом создании элемента), и обновить его изменяет каждый раз при сохранении элемента.

Я проделал то же самое с другими проектами, которые написал с помощью Django, и поэтому ваш save () будет выглядеть так:

from django.utils import timezone

class User(models.Model):
    created     = models.DateTimeField(editable=False)
    modified    = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = timezone.now()
        self.modified = timezone.now()
        return super(User, self).save(*args, **kwargs)

Надеюсь, это поможет!

Изменить в ответ на комментарии:

Причина, по которой я просто придерживаюсь перегрузки save () вместо того, чтобы полагаться на эти аргументы поля, двоякая:

  1. Вышеупомянутые взлеты и падения с их надежностью. Эти аргументы в значительной степени зависят от того, как каждый тип базы данных, с которой Django знает, как взаимодействовать, обрабатывает поле метки даты / времени и, кажется, ломается и / или изменяется между каждым выпуском. (Я считаю, что это послужило толчком для их полного удаления.)
  2. Тот факт, что они работают только с DateField, DateTimeField и TimeField, и с помощью этого метода вы можете автоматически заполнять любой тип поля каждый раз при сохранении элемента.
  3. Используйте django.utils.timezone.now () vs. datetime.datetime.now () , потому что он вернет объект с учетом TZ или наивный datetime.datetime в зависимости от settings.USE_TZ .

Чтобы выяснить, почему OP обнаружил ошибку, Я не знаю точно, но похоже, что created вообще не заполняется, несмотря на то, что auto_now_add = True . Для меня это выделяется как ошибка и подчеркивает пункт №1 в моем небольшом списке выше: auto_now и auto_now_add в лучшем случае ненадежны.

потому что он вернет наивный объект datetime.datetime в зависимости от settings.USE_TZ .

Чтобы выяснить, почему OP обнаружил ошибку, я точно не знаю , но похоже, что created даже не заполняется, несмотря на то, что auto_now_add = True . Для меня это выделяется как ошибка и подчеркивает пункт №1 в моем небольшом списке выше: auto_now и auto_now_add в лучшем случае ненадежны.

потому что он вернет наивный объект datetime.datetime в зависимости от settings.USE_TZ .

Чтобы выяснить, почему OP обнаружил ошибку, я точно не знаю , но похоже, что created даже не заполняется, несмотря на то, что auto_now_add = True . Для меня это выделяется как ошибка и подчеркивает пункт № 1 в моем небольшом списке выше: auto_now и auto_now_add в лучшем случае ненадежны.

и подчеркивает пункт №1 в моем небольшом списке выше: auto_now и auto_now_add в лучшем случае ненадежны.

и подчеркивает пункт №1 в моем небольшом списке выше: auto_now и auto_now_add в лучшем случае ненадежны.

346
ответ дан 23 November 2019 в 02:57
поделиться

Это повод для беспокойства?

Нет, Django автоматически добавляет его за вас при сохранении моделей, так что это ожидаемо.

Дополнительный вопрос: в моем инструменте администратора эти 2 поля не отображаются. Ожидается ли это?

Поскольку эти поля добавляются автоматически, они не отображаются.

Чтобы добавить к вышесказанному, как сказал synack, в списке рассылки django были дебаты, чтобы удалить это, потому что это "плохо спроектирован" и является "хитростью"

. Написание пользовательского save () для каждой из моих моделей намного сложнее, чем использование auto_now

. Очевидно, вам не нужно писать его для каждой модели. Вы можете записать его в одну модель и наследовать от нее другие.

Но поскольку есть auto_add и auto_now_add , я бы использовал их, а не пытался написать метод сам.

5
ответ дан 23 November 2019 в 02:57
поделиться

Но я хотел отметить, что мнение, выраженное в принятом ответе, несколько устарело. Согласно более поздним обсуждениям (django bugs #7634 и #12785), auto_now и auto_now_add никуда не денутся, и даже если вы обратитесь к оригинальному обсуждению, вы найдете сильные аргументы против RY (как в DRY) в пользовательских методах сохранения.

Было предложено лучшее решение (пользовательские типы полей), но оно не получило достаточного импульса, чтобы войти в django. Вы можете написать свой собственный в три строки (это предложение Джейкоба Каплан-Мосса).

from django.db import models
from django.utils import timezone


class AutoDateTimeField(models.DateTimeField):
    def pre_save(self, model_instance, add):
        return timezone.now()

#usage
created_at = models.DateField(default=timezone.now)
updated_at = models.AutoDateTimeField(default=timezone.now)
159
ответ дан 23 November 2019 в 02:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: