具有ManyToMany字段的Diff django模型对象

del*_*boy 1 python django diff models

我有一种情况,当DB中的某些内容发生变化时,我需要通知某些用户.我的想法是抓住pre_savepost_save发出信号并制作某种差异和邮件.一般来说它运作良好,但我不知道如何获得m2m字段的差异.

目前我有这样的事情:

def pre_save(sender, **kwargs):
    pk = kwargs['instance'].pk
    instance = copy.deepcopy(sender.objects.get(pk=pk))
    tracking[sender] = instance

def post_save(sender, **kwargs):
    instance = copy.deepcopy(kwargs['instance'])
    print diff(instance, (tracking[sender])) # TODO: don't print, save diff somewhere
Run Code Online (Sandbox Code Playgroud)

Diff函数应该适用于每个模型(在mommet我有四个模型类).使用深度复制,我可以保存旧模型,但我不知道如何保存m2m字段,因为它们在单独的表中(是的,我知道我可以获得这些数据,但在执行的时候我不知道哪些字段是m2m,我不想为每个型号创建不同的插槽).我想要的是通用解决方案,所以我可以稍后添加模型而不考虑通知部分.

我的计划是在调用插槽后调用get_data()clear_data()运行save(),以清理插槽生成的差异.

这是这样做的好方法吗?有没有更好的办法?是否有能为我做这项工作的django应用程序?

请原谅我的英语,这不是我的母语.

Chr*_*ard 6

首先,您不需要使用deepcopy.从数据库中重新查询发件人将返回"新鲜"对象.

def pre_save(sender, **kwargs):
    pk = kwargs['instance'].pk
    instance = sender.objects.get(pk=pk)
    tracking[sender] = instance
Run Code Online (Sandbox Code Playgroud)

您可以获取类的所有多对多字段的列表,并检查与当前实例相关的值:

for field in sender._meta.local_many:
    values = field.value_from_object(instance).objects.all()
    # Now values is a list of related objects, which you can diff
Run Code Online (Sandbox Code Playgroud)