django-reversion icon indicating copy to clipboard operation
django-reversion copied to clipboard

VersionAdmin overwrites my reversion comment set under MyAdmin.save_model

Open tuttle opened this issue 2 years ago • 1 comments

First, thank you for this very useful project!

If I may, I have a simple context manager


@contextmanager
def create_op_revision(self, **comment):
    with reversion.create_revision() as ctx:
        comment.update(param1='a', param2='b')
        reversion.set_comment(
            json.dumps(comment)
        )
        yield ctx

because I wish to store some structured data with revisions and I use my context manager in various places and it works. But when I call it from the overriden save_model like this:


class MyAdmin(VersionAdmin):
    def save_model(...):
        with create_op_revision(some_info='abc'):
            ... my ORM code ...

then the VersionAdmin.log_addition overwrites my comment with the string "Added.", because it does not care about the previous comment:


class VersionAdmin:
    def log_addition(self, request, object, message):
        change_message = message or _("Initial version.")
        entry = super().log_addition(request, object, change_message)
        if is_active():
            set_comment(entry.get_change_message())
        return entry

VersionAdmin.log_change does the same.

It would be great, for example, if VersionAdmin.log_* adds its message to the dict in case there is JSON, resulting to something like this in my case:

Revision.comment = {
    'some_info': 'abc',
    'param1': 'a',
    'param2': 'b',
    'admin_message': "Added."
}

Thank you for considering.

tuttle avatar May 16 '22 12:05 tuttle

Today I discovered another effect of what VersionAdmin.log_addition does:

As VersionAdmin.changelist_view wraps entire super().changelist_view(...) in create_revision, so all actions get wrapped. Admin actions are designed to work on multiple objects.

I didn't find a way to make a separate reversion for each object creation/change in the action function.

Even if I reduce my demands to only have a separate log message for individual objects using log_addition/log_change, then the same as before happens: The last message prevails, the previous ones are overwritten.

The entire revision has comment belonging to the latest object processed in the action queryset.

tuttle avatar May 17 '22 07:05 tuttle

I think you can implement this feature yourself using reversion.get_comment and reversion.set_comment. You can use these together to append content to an existing comment, rather than override it.

etianen avatar Oct 02 '22 15:10 etianen