1

我正在编写一个 Django 应用程序,它将以类似于管理界面的方式跟踪模型的更改。例如,我将能够显示对模型的更改列表,看起来像Changed Status from Open to Closed.

我正在使用 pre_save 信号来执行此操作,比较数据库中现有项目和正在保存的“实例”之间的相关字段。要获得现有项目,我必须这样做sender._default_manager.get(pk=sender.pk)看起来有点乱,但那部分有效。

问题是,更改此模型的视图调用save()表单上的方法两次(第一次使用 commit=False) - 这意味着数据库中记录了 2 次更改,因为 pre_save 信号被发出两次。

有什么办法可以做到这一点吗?也许以完全不同的方式,虽然我记得读过 Django 管理应用程序使用信号来跟踪用户所做的更改。

4

3 回答 3

3

查看 Django 源代码,似乎pre_save每次调用 save 时都会发送信号,即使commitfalse. 我建议在第一个上插入pre_save,但在更改表中添加一个标志列,例如

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)

然后,您的预存可以是:

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 以确保您不会在下一次Foostatus更改中获取它。

于 2009-06-15T04:39:46.800 回答
1

使用 dispatch_uid:

http://docs.djangoproject.com/en/1.2/topics/signals/#preventing-duplicate-signals

于 2011-03-06T13:54:20.537 回答
0

Django 审计日志

django-audit-log是一个可插入的应用程序,它可以轻松完成您想要的工作。我已经在一个项目中使用过它,而且我现在肯定会在更多的地方使用它。

于 2011-05-24T14:27:24.380 回答