python post_save 在 Django 中立即更新实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1640744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
post_save in django to update instance immediately
提问by givp
I'm trying to immediately update a record after it's saved. This example may seem pointless but imagine we need to use an API after the data is saved to get some extra info and update the record:
我试图在保存后立即更新记录。这个例子可能看起来毫无意义,但想象一下我们需要在保存数据后使用 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)
So the 'extra' field is supposed to be set to 'hello' after each save. Correct? But it's not working.
因此,每次保存后都应该将“额外”字段设置为“你好”。正确的?但它不起作用。
Any ideas?
有任何想法吗?
回答by ozan
When you find yourself using a post_save signal to update an object of the sender class, chances are you should be overriding the save method instead. In your case, the model definition would look like:
当您发现自己使用 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)
回答by Paul McMillan
Doesn't the post_save handler take the instance? Why are you filtering using it? Why not just do:
post_save 处理程序不采用实例吗?为什么要使用它进行过滤?为什么不这样做:
def my_handler(sender, instance=False, created, **kwargs):
if created:
instance.blah = 'hello'
instance.save()
Your existing code doesn't work because it loops, and Test.objects.filter(id=instance.id)
returns a query set, not an object. To get a single object directly, use Queryset.get()
. But you don't need to do that here. The created argument keeps it from looping, as it only sets it the first time.
您现有的代码不起作用,因为它循环并Test.objects.filter(id=instance.id)
返回一个查询集,而不是一个对象。要直接获取单个对象,请使用Queryset.get()
. 但你不需要在这里这样做。created 参数防止它循环,因为它只在第一次设置它。
In general, unless you absolutely need to be using post_save signals, you should be overriding your object's save() method anyway.
通常,除非您绝对需要使用 post_save 信号,否则无论如何您都应该覆盖对象的 save() 方法。