在Django中使用post_save立即更新实例
我想在保存记录后立即更新它。这个例子看起来可能没什么意义,但想象一下,我们需要在数据保存后使用一个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)
所以“extra”这个字段应该在每次保存后被设置为“hello”。对吧?但是它没有正常工作。
有什么想法吗?
2 个回答
6
这个 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()
。不过在这里其实不需要这么做。因为 created 参数可以防止循环,它只在第一次设置的时候起作用。
一般来说,除非你真的需要使用 post_save 信号,否则你应该重写对象的 save() 方法。
21
当你发现自己在使用 post_save 信号来更新发送者类的对象时,可能更应该考虑重写 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)