Когда обновление/создавание выполняется на модели Django (.save()
) Я хотел бы смочь "вступить" и сравнить некоторые конкретные атрибуты с тем, на что они были установлены ранее (если они ранее существовали вообще).
Я думаю, Предварительно сохраняют Сигналы, с поиском к исходной модели, делающей a .objects.get(instance.id)
, но это чувствует себя расточительным. Кроме того, имеет проверку, уже произошел в pre_save()
?
о проверке модели :
Обратите внимание, что full_clean () не будет вызываться автоматически, когда вы вызываете метод save () вашей модели
Затем о сигнал предварительного сохранения
, обратите внимание, что вы получаете экземпляр, который сохраняется, отправленный как параметр с сообщением. Поскольку предыдущая версия вашей модели существует только в базе данных, я не вижу, где еще вы могли бы получить предыдущее значение атрибутов ...
Вы не говорите, почему вы хотите это сделать, поэтому трудно скажем, но другие решения, о которых я думаю прямо сейчас:
* defining a custom signal that is sent everytime the attributes you are interested in are modified... This signal would then send two arguments : new value, old value
* perform the check directly when setting the attributes
Если вы дадите более подробную информацию, это может быть проще ...
РЕДАКТИРОВАТЬ:
Верно ... Если вы создадите собственный 'foo_has_updated' , вы не будете уверены, что модификация сохранена.
В этом случае, я думаю, вы могли бы кэшировать интересующие вас переменные при инициализации экземпляра и перехватить сигнал после сохранения ИЛИ до сохранения.
* With pre-save, you would be able to pre-process the data, but the saving operation might fail
* With post-save, you would be sure that the data has been saved.
Кэширование ваших переменных может быть выполнено так:
class CachedModel(models.Model):
cached_vars = [var1, var2, varN]
def __init__(self, *args, **kwargs):
super(CachedModel, self).__init__(*args, **kwargs)
self.var_cache = {}
for var in self.cached_vars:
self.var_cache[var] = copy.copy(getattr(self, var))
Или что-то вроде этого ... Затем в вашем обработчике сигналов:
def post_save_handler(sender, **kwargs):
instance = kwargs["instance"]
[(instance.var_cache[var], getattr(instance, var)) for var in instance.cached_var]
#[(<initial value>, <saved value>)
И вы получили то, что вам нужно (я думаю) !!!
Вы можете запросить текущие сохраненные значения в базе данных перед сохранением. Я сделал это, чтобы регистрировать только измененные значения, но при каждом сохранении это вызывает новый запрос к базе данных.
Хотя я очень одобряю ответ Себастьяна Пикемаля , в конечном итоге я использовал оба сигналы pre_save
и post_save
. Вместо переопределения __init__()
я делаю что-то очень похожее в pre_save
, а затем проверяю/сравниваю значения в post_save
и выдаю пользовательский сигнал оттуда, если выполняются определенные условия.
Думаю, я все же приму его ответ, учитывая время, потраченное на него. Я не вижу, в чем мы сильно отличаемся, за исключением того, что я делаю свою работу в сигнале, а он делает это во время инициализации.