когда использовать pre save, save, post save в django?

Я вижу, что могу переопределить или определить pre_save, save, post_save делать то, что я хочу, когда экземпляр модели сохраняется.

какой из них предпочтительнее в какой ситуации и почему?

3 ответов


я постараюсь объяснить это на примере:

pre_save и post_save are сигналы отправляет модели. Проще говоря, действия, которые нужно предпринять до или после модели save называется.

A save запускает следующие шаги

  • Испустите сигнал пре-спасения.
  • предварительная обработка данных.
  • большинство полей не предварительная обработка-данные поля сохраняются как есть.
  • подготовка данных для базы данных.
  • вставить данные в базу данных.
  • излучают сигнал после сохранения.

Django предоставляет способ переопределить эти сигналы.

теперь

pre_save сигнал может быть переопределен для некоторой обработки, прежде чем произойдет фактическое сохранение в базу данных - пример: (я не знаю хороший пример того, где pre_save будет идеал на макушке)

допустим, у вас есть ModelA который хранит ссылку на все объекты ModelB, которые не отредактировано. Для этого вы можете зарегистрировать pre_save сигнал уведомления ModelA перед ModelB ' s save метод вызывается (ничто не мешает вам зарегистрировать post_save сигнал здесь тоже).

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

class ModelB(models.Model):
    def save(self):
        #do some custom processing here: Example: convert Image resolution to a normalized value
        super(ModelB, self).save()

затем вы можете зарегистрировать post_save сигнал (это больше используется, что pre_save)

общий usecase является UserProfile создание объектов, когда User объект создается в системе.

вы можете зарегистрировать post_save сигнал, который создает UserProfile объект, который соответствует каждому User в системе.

сигналы-это способ сохранить модульность и явность. (Явно уведомить ModelA если я save или изменить что-то в ModelB )

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


pre_save

он используется до сохранения транзакции.

post_save

он используется после сохранения транзакции.

можно использовать pre_save например, если у вас есть FileField или ImageField и Ли file или image действительно существует.

можно использовать post_save когда у вас есть UserProfile и вы хотите создать новый на данный момент новый User он создан.


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

сигнал.отсоединить (приемник=нет, отправитель=нет, dispatch_uid=нет) [источник] для отключения приемника от сигнала, сигнал вызова.разъединять.)( Аргументы приведены в Сигнал.связываться.)( Метод возвращает True, если получатель отключено и ложно, если нет.

аргумент receiver указывает зарегистрированный приемник для отключения. Это может быть None, если dispatch_uid используется для идентификации получателя.

... и подключите его снова после.

update () метод не отправляет сигналы pre_ и post_, имейте это в виду.