当所谓的Django pre_save信号提交=假
-
13-09-2019 - |
题
我写一个Django应用程序,将跟踪更改模型,以类似的方式来管理界面。例如,我将能够显示更改为模型,看起来像Changed Status from Open to Closed
的列表。
我现在用的是pre_save信号要做到这一点,在数据库中比较现有项目的相关领域,并且被保存在“实例”。为了让现有的项目,我需要做的sender._default_manager.get(pk=sender.pk)
这似乎有点混乱,但是这部分的工作。
的问题是,用于改变该模型的视图调用表格上的save()
方法两次(先用提交=假) - 这意味着2度的变化得到记录在数据库中,作为pre_save信号被发射两次。 p>
有没有什么办法可以做到这一点?也许在一个完全不同的方式,但我记得读了Django管理应用程序使用信号来跟踪更改用户做。
解决方案
通过Django的源寻找,似乎pre_save
信号在每一个呼叫发送到保存,即使是commit
false
。我建议插入在第一pre_save
,但标志列添加到变化表,e.g。
class FooChanges(models.Model):
foo = models.ForeignKey(Foo)
dt = models.DateTimeField(default=datetime.now)
field = models.CharField(max_length=50)
value = models.CharField(max_length=50) # Or whatever is appropriate here
finished = models.BooleanField(default=False)
然后,你的presave可以是:
def pre_save_handler(sender, instance):
foo_changes, created = FooChanges.objects.get_or_create(foo=instance, finished=False, field='Status', value=instance.status)
if not created:
foo_changes.finished = True
foo_changes.save()
所以第一pre_save
,你居然插入变化。在第二遍,你从数据库中检索,并设置标志设置为false,以确保你没有把它捡起来,下一次Foo
的status
变化。
其他提示
Django的审计日志
Django的审计日志是一个可插拔的应用程序,不正是你想要什么举手之劳。我用它在一个项目中,我肯定会在更多的现在,我知道它使用它。
不隶属于 StackOverflow