Django: cannot detect changes on many-to-many field with m2m_changed signal - auditing at model-level

时间秒杀一切 提交于 2019-11-27 21:55:24

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/4744794/django-cannot-detect-changes-on-many-to-many-field-with-m2m-changed-signal-au

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!