Лучший способ добавить общие date_added, date_modified ко многим моделям в Django

Я добавляю поля date_added и date_modified к набору общих моделей в моем текущем проекте. Я создаю подклассы models.Model и добавляю соответствующие поля, но я хочу добавить автоматическое поведение сохранения (т.е. каждый раз, когда кто-либо вызывает MyModel.save(), поле date_modified обновляется. Я вижу два подхода: переопределение метода save() или добавление обработчика сигнала pre_save в абстрактный базовый класс.

class CommonData(models.Model):
    date_added = models.DateTimeField(default=datetime.datetime.today,null=False,blank=False)
    date_modified = models.DateTimeField(default=datetime.datetime.today,null=True,blank=True)

    # register a handler for the pre_save to update date_modified
    def pre_save_handler(sender, **kwargs):
        date_modified = datetime.datetime.today

    def __init__():
        pre_save.connect(pre_save_handler, sender=self)

or

class CommonData(models.Model):
    date_added = models.DateTimeField(default=datetime.datetime.today,null=False,blank=False)
    date_modified = models.DateTimeField(default=datetime.datetime.today,null=True,blank=True)

    # overriding save 
    def save(force_insert=False,force_update=False):
        date_modified = datetime.datetime.now
        return models.Model.save(force_insert, force_update)

Я новичок в Django и Python, и мне интересно, какой подход был более «джанго»? Что эффективнее? какой "правильный" способ сделать это?


person Deano    schedule 24.12.2009    source источник


Ответы (4)


Поскольку вы новичок в Django, вам могут пригодиться расширения команд Django:

http://code.google.com/p/django-command-extensions/< /а>

... который удобно включает TimeStampedModel, из которого вы можете получить свои модели:

http://code.google.com/p/django-command-extensions/wiki/ModelExtensions

Модель абстрактного базового класса, предоставляющая самоуправляемые «созданные» и «измененные» поля.

person nikola    schedule 24.12.2009
comment
спасибо prometheus, я не знал о расширениях команд. Я люблю python/django ... однако есть много способов сделать что-то! - person Deano; 28.12.2009

Вы пытались посмотреть на auto_now=True и auto_now_add=True DateTimeField? Они автоматически делают то, что вам нужно. В противном случае нет реальной разницы между переопределением сохранения и обработкой сигнала - фактически сигнал pre_save вызывается из метода сохранения модели django.

Документы: http://docs.djangoproject.com/en/dev/ref/models/fields/#datefield

person kibitzer    schedule 24.12.2009
comment
auto_now и auto_now_add теперь считаются ненадежными. Лучше установить даты в методе сохранения. Это то, что используют другие предлагаемые решения (с ABC). - person hopla; 16.07.2010

Вы можете определить их в абстрактном базовом классе, а затем наследовать от этого. Это похоже на MixIn, который также определяет поля модели.

person Peter Rowell    schedule 24.12.2009
comment
Спасибо, Питер, это то, что я делал, мой вопрос был немного больше о лучшем способе реализации функциональности по умолчанию: переопределение методов сигналов или методов. Я предполагаю, что сигнал больше похож на миксин, а переопределение метода больше похоже на функциональность по умолчанию, нет? - person Deano; 24.12.2009
comment
Вы правы, я двигался слишком быстро без достаточного количества кофеина. Ответ Кибитцера точен. - person Peter Rowell; 24.12.2009

Обратите внимание, что auto_now_add и auto_now используют pre_save, что не работает, когда bulk_create или update. Таким образом, в вашем MySQL, например, поле date_added будет «0000-00-00 00:00:00», и можно получить предупреждение: «Предупреждение: столбец «date_added» не может быть нулевым». Так что вы можете использовать auto_now*, но будьте осторожны.

person znotdead    schedule 22.01.2013