Я вижу, что могу переопределить или определить pre_save, save, post_save
, чтобы делать то, что я хочу, когда экземпляр модели будет сохранен.
Какой из них предпочтительнее, в какой ситуации и почему?
Я вижу, что могу переопределить или определить pre_save, save, post_save
, чтобы делать то, что я хочу, когда экземпляр модели будет сохранен.
Какой из них предпочтительнее, в какой ситуации и почему?
Я попытаюсь изо всех сил объяснить это с помощью примера:
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
)
Я подумаю о более конкретных примерах реального мира, чтобы лучше ответить на этот вопрос. Между тем, я надеюсь, что это поможет вам
pre_save
который использовался до транзакции.
post_save
он используется после сохранения транзакции.
Вы можете использовать pre_save
, например, если у вас есть FileField
или ImageField
и посмотрите, действительно ли существует file
или image
.
Вы можете использовать post_save
, когда у вас есть UserProfile
, и вы хотите создать новый в момент создания нового User
.
Не забывайте о риске рекурсий. Если вы используете метод post_save при вызове instance.save(), вместо метода .update, вы должны отключить сигнал post_save:
Signal.disconnect(приемник = нет, отправитель = нет, dispatch_uid = None) [источник] Чтобы отключить приемник от сигнала, вызовите Signal.disconnect(). Аргументы приведены в Signal.connect(). Метод возвращает True, если получатель отключен и False, если нет.
Аргумент приемника указывает, что зарегистрированный приемник отключается. Он может быть None, если dispatch_uid используется для идентификации получателя.
... и снова подключите его.
update() метод не отправляет сигналы pre_ и post_, помните об этом.