我很难从django掌握这个post_save / pre_save信号。
我的模型有一个名为status
的字段,当添加/保存此模型的条目时,必须根据某些条件相应地更改其状态。
我的模型看起来像这样:
class Ticket(models.Model):
(...)
status = models.CharField(max_length=1,choices=OFFERT_STATUS, default='O')
我的信号处理程序,配置为pre_save:
def ticket_handler(sender, **kwargs):
ticket = kwargs['instance']
(...)
if someOtherCondition:
ticket.status = 'C'
现在,如果我将ticket.save()
放在最后一行if
语句中,会发生什么,这是一个巨大的迭代黑洞,因为这个动作会调用信号本身。这个问题同时发生在pre_save
和post_save
。
嗯......我想在django的宇宙中,在保存它之前(甚至之后)改变一个条目的能力是很常见的。那么,我在这里做错了什么?信号是错误的方法还是我错过了其他的东西?
此外,一旦触发了pre_save / post_save函数,是否可以访问另一个模型的实例并更改其上的特定行条目?
由于
答案 0 :(得分:7)
在保存之前,信号不是更新同一模型中的字段的正确方法。覆盖模型的保存方法,而不是使用此情况下的信号。
def save(self, force_insert=False, force_update=False):
status = whatever....
super(Ticket, self).save(force_insert, force_update)
对于其他型号的更新,信号是一种很好的方法,因为您可以轻松地将模型分离。具体来说,您可以添加pre_ / post_save信号来触发操作,而无需修改已保存模型的代码(可能驻留在第三方的另一个应用程序中)。
答案 1 :(得分:3)
我同意Carles的说法,这可能属于save()
。当必须使用信号执行此操作时,请确保save()
周围的情况非常紧张。您的测试可以重新编写为:
if someOtherCondition and ticket.status != 'C':
ticket.status = 'C'
ticket.save()
通过这种方式进行测试,你不会进入无限递归。