Django:无法通过m2m_changed信号检测多对多字段的变化 - 在模型级别进行审计 [英] Django: cannot detect changes on many-to-many field with m2m_changed signal - auditing at model-level

查看:402
本文介绍了Django:无法通过m2m_changed信号检测多对多字段的变化 - 在模型级别进行审计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想跟踪任何模型的哪个领域发生了变化(即,在模型级别审核,因为它更加原子,而不是像管理员/表单级别,就像django和django-reversion可以已经做的那样)。我可以使用前/后保存/删除信号来做任何事情。但是,我有一个在m2m字段上这样做的问题。



对于下面的代码示例,我在用户更改表单中定义custom_groupsm2m字段,因为它是一个反向关系。例如,当用户将表单保存在管理界面上时,如果custom_groups字段中有更改,我想记录。



型号:

  from django.contrib.auth.models import User 

class CustomGroup(models.Model) :
users = models.ManyToManyField(User,related_name ='custom_groups')

ModelForm:

  class CustomUserChangeForm(UserChangeForm):
custom_groups = forms.ModelMultipleChoiceField(required = False ,queryset = CustomGroup.objects.all())

使用m2m_changed信号的问题是我可以在使用赋值运算符更新m2m字段的情况下,检查实际发生了什么变化:

  user.custom_groups = self。 clean_data ['custom_groups'] 

这是因为内部django将在* custom_groups *上执行clear() ,之前手动添加所有对象。这将执行前/后清除,然后在m2m字段上保存/保存。



我做错了吗?有一个更简单的方法可以实际工作吗?



谢谢!

解决方案

我有一个类似的问题,我想我可以解决它。我不知道你如何使用m2m_changed,但它应该在models.py上,应该类似于这样:

  signals.m2m_changed.connect(your_function,sender = CustomGroup.users.through)

现在,我将创建一个包含该函数的signals.py文件,以下代码将打印您选择的选项:

  def your_function(sender,instance,action,reverse,model,pk_set,** kwargs):
if action =='post_add':
for pk_set:
print val

现在,您知道更新的值。我希望这可以解决你的问题。


I'd like to keep track on what field has changed on any model (i.e. audit at model level since it's more atomic, not at admin/form-level like what django and django-reversion can already do). I'm able to do that for any field using pre/post save/delete signals. However, I have a problem of doing that on an m2m field.

For the code sample below, i define 'custom_groups' m2m field in user change form since it's a reverse relation. When user saves the form on admin interface for example, I'd like to log if there's a change in 'custom_groups' field.

Model:

from django.contrib.auth.models import User

class CustomGroup(models.Model):
    users = models.ManyToManyField(User, related_name='custom_groups')

ModelForm:

class CustomUserChangeForm(UserChangeForm):
    custom_groups = forms.ModelMultipleChoiceField(required=False, queryset=CustomGroup.objects.all())

The problem with using m2m_changed signal is that i can't check what has actually changed for the case where the m2m field is updated using assignment operator:

user.custom_groups = self.cleaned_data['custom_groups']

This is because internally django will perform a clear() on *custom_groups*, before manually adding all objects. This will execute pre/post-clear and then pre/post save on the m2m field.

Am I doing all this the wrong way? Is there a simpler method that can actually work?

Thanks!

解决方案

I had a similar problem and I think I could solve it. I don't know how you are using the m2m_changed but it should be on models.py and should be similar to something like this:

signals.m2m_changed.connect(your_function, sender=CustomGroup.users.through)

Now, I would create a signals.py file containing that function, and the following code should print you the options that you have selected:

def your_function(sender, instance, action, reverse, model, pk_set, **kwargs):
    if action == 'post_add':
        for val in pk_set:
            print val

Now, you know the updated values. I hope this could solve your problem.

这篇关于Django:无法通过m2m_changed信号检测多对多字段的变化 - 在模型级别进行审计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆