Django: Прежде чем модель обновляется, я хотел бы “посмотреть” на ее предыдущие атрибуты

Когда обновление/создавание выполняется на модели Django (.save()) Я хотел бы смочь "вступить" и сравнить некоторые конкретные атрибуты с тем, на что они были установлены ранее (если они ранее существовали вообще).

Я думаю, Предварительно сохраняют Сигналы, с поиском к исходной модели, делающей a .objects.get(instance.id), но это чувствует себя расточительным. Кроме того, имеет проверку, уже произошел в pre_save()?

13
задан anonymous coward 9 July 2010 в 20:26
поделиться

3 ответа

о проверке модели :

Обратите внимание, что 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>)

И вы получили то, что вам нужно (я думаю) !!!

7
ответ дан 2 December 2019 в 01:31
поделиться

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

0
ответ дан 2 December 2019 в 01:31
поделиться

Хотя я очень одобряю ответ Себастьяна Пикемаля , в конечном итоге я использовал оба сигналы pre_save и post_save. Вместо переопределения __init__() я делаю что-то очень похожее в pre_save, а затем проверяю/сравниваю значения в post_save и выдаю пользовательский сигнал оттуда, если выполняются определенные условия.

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

0
ответ дан 2 December 2019 в 01:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: