Post_save в django для немедленного обновления экземпляра
Я пытаюсь немедленно обновить запись после ее сохранения. Этот пример может показаться бессмысленным, но представьте, что нам нужно использовать API после сохранения данных, чтобы получить дополнительную информацию и обновить запись:
def my_handler(sender, instance=False, **kwargs):
t = Test.objects.filter(id=instance.id)
t.blah = 'hello'
t.save()
class Test(models.Model):
title = models.CharField('title', max_length=200)
blah = models.CharField('blah', max_length=200)
post_save.connect(my_handler, sender=Test)
Таким образом, для каждого сохранения должно быть установлено "дополнительное" поле "hello". Верный? Но он не работает.
Любые идеи?
Ответы
Ответ 1
Когда вы обнаруживаете, что используете post_save сигнал для обновления объекта класса отправителя, скорее всего, вы должны переопределить метод сохранения. В вашем случае определение модели будет выглядеть следующим образом:
class Test(models.Model):
title = models.CharField('title', max_length=200)
blah = models.CharField('blah', max_length=200)
def save(self, force_insert=False, force_update=False):
if not self.blah:
self.blah = 'hello'
super(Test, self).save(force_insert, force_update)
Ответ 2
Не обрабатывает ли обработчик post_save экземпляр? Почему вы фильтруете его? Почему бы просто не сделать:
def my_handler(sender, instance=False, created, **kwargs):
if created:
instance.blah = 'hello'
instance.save()
Существующий код не работает, потому что он петли, а Test.objects.filter(id=instance.id)
возвращает набор запросов, а не объект. Чтобы получить один объект напрямую, используйте Queryset.get()
. Но вам здесь не нужно это делать. Созданный аргумент сохраняет его от цикла, поскольку он устанавливает его только в первый раз.
В общем случае, если вам абсолютно не нужно использовать сигналы post_save, вы все равно должны переопределять метод save().