Я вижу, что могу переопределить или определить 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_, помните об этом.