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().