Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for tracking changes in from django admin inlines m2m #638

Open
alexkiro opened this issue Apr 30, 2024 · 2 comments
Open

Add support for tracking changes in from django admin inlines m2m #638

alexkiro opened this issue Apr 30, 2024 · 2 comments
Labels

Comments

@alexkiro
Copy link

When using django admin inlines for M2M relationships, there is documented limitation that means m2m_changed signal isn't triggered. From django docs:

Note that when using this technique the m2m_changed signals aren’t triggered. This is because as far as the admin is concerned, through is just a model with two foreign key fields rather than a many-to-many relation.


Because of this limitations all changes done via the admin inlines for M2M relationships are not logged.

@hramezani
Copy link
Member

django-auditlog uses the m2m_changed signal and connects a receiver function to the signal. So, If the signals aren't triggered, django-auditlog can't receive it.

As it is a limitation in Django, I am not sure that we can find an easy way to implement this feature.

@alexkiro
Copy link
Author

alexkiro commented May 1, 2024

As it is a limitation in Django, I am not sure that we can find an easy way to implement this feature.

Yep, it does seem quite tricky to pull of, can't think of any good way to implement this.

I did manage to find a workaround, however could not figure any clean way to integrate this directly with django-auditlog. Adding my workaround here, in case anyones else runs into this issue and needs some inspiration.


The idea is to override the save_related method of the ModelAdmin and create the log entries manually. Could not find any neat way to introspect arguments, so they are all harcoded.

    def save_related(self, request, form, formsets, change):
        super().save_related(request, form, formsets, change)

        for formset in formsets:
            # M2M logging doesn't work in inline models, so create them manually here.
            # See upstream: https://github.com/jazzband/django-auditlog/issues/638
            if formset.model == Contact.groups.through:
                LogEntry.objects.log_m2m_changes(
                    [obj.contactgroup for obj in formset.deleted_objects],
                    formset.instance,
                    "delete",
                    "groups",
                )
                LogEntry.objects.log_m2m_changes(
                    [obj.contactgroup for obj in formset.new_objects],
                    formset.instance,
                    "add",
                    "groups",
                )

This solution also has the limitation that it won't work with updates in the m2m inline. Only add/delete, so only can be used safely if you have changes disabled in inline. That is done with adding the following method:

    def has_change_permission(self, request, obj=None):
        return False

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants