Когда использовать pre_save, save, post_save в django?

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

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

Ответы

Ответ 1

Я попытаюсь изо всех сил объяснить это с помощью примера:

pre_save и post_save signals, которые отправляются моделью. В более простых словах вызывается действие, выполняемое до или после модели save.

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

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

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

Теперь,

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

Предположим, что у вас есть ModelA, в котором хранится ссылка на все объекты ModelB, которые еще не были изменены не. Для этого вы можете зарегистрировать сигнал pre_save, чтобы уведомить ModelA непосредственно перед вызовом метода ModelB 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)

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

Ответ 2

pre_save

который использовался до транзакции.

post_save

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

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

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

Ответ 3

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

Signal.disconnect(приемник = нет, отправитель = нет, dispatch_uid = None) [источник] Чтобы отключить приемник от сигнала, вызовите Signal.disconnect(). Аргументы приведены в Signal.connect(). Метод возвращает True, если получатель отключен и False, если нет.

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

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

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