Skip to main content
 首页 » 编程设计

python之使用 ManyToMany 字段区分 Django 模型对象

2025年05月04日36leader

我有一种情况,当数据库中的某些内容发生变化时,我需要通知一些用户。我的想法是捕获 pre_save 和 post_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 

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

我的计划是在 save() 之后调用 get_data() 和 clear_data() 函数,以清除插槽生成的差异.

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

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

请您参考如下方法:

首先,您不需要为此使用深度复制。从数据库中重新查询发件人会返回一个"new"对象。

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

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

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