lazybird/django-solo

django-reversion integration

sobolevn opened this issue · 4 comments

Usecase

I want to have a singleton object with versions.

Integration

At first the were several issues with integrating it all together.

reversion/admin.py:

def change_view(self, request, object_id, form_url='', extra_context=None):
        with self.create_revision(request):
            # ugly hack to make it work:
            return admin.ModelAdmin.change_view(self, request, object_id, form_url, extra_context)

solo/admin.py:

    def change_view(self, request, object_id, extra_context=None, form_url='/'):
        if object_id == '1':
            self.model.objects.get_or_create(pk=1)
        return super(SingletonModelAdmin, self).change_view(
            request,
            object_id,
            form_url=form_url,  # this parameter was required
            extra_context=extra_context,
        )

and my own admin.py:

from solo.admin import SingletonModelAdmin
from reversion.admin import VersionAdmin

class MyModelAdmin(VersionAdmin, SingletonModelAdmin):
    pass  # it does not work with `MyModelAdmin(SingletonModelAdmin, VersionAdmin)`

admin.site.register(Document, MyModelAdmin)

TODO

  1. I have not tried to run any tests
  2. Ugly hack with admin.ModelAdmin.change_view(self, ...) should be changed
  3. Any other things to keep in mind?

Demo

2016-06-26 14 41 04

2016-06-26 14 40 56

2016-06-26 14 40 49

django-reversion author here!

I don't know the specifics of how django-solo manages it's admin, but django-reversion will save a revision whenever all the following are met:

  1. The model is registered with reversion.
  2. The view is decorated with create_revision().
  3. The model's save() method is called.

I'd expect that all you need to do is this:

class MyModelAdmin(VersionAdmin, SingletonModelAdmin):
    pass

And that no other hacks would be required. What problems were you encountering that required the hacks in the first place?

Thanks! The detailed information.

First issue:

TypeError at /admin/documents_app/document/
change_view() takes at most 4 arguments (5 given)
/Users/sobolev/.virtualenvs/localphoto/lib/python2.7/site-packages/reversion/admin.py in change_view
return super(VersionAdmin, self).change_view(request, object_id, form_url, extra_context) ...

The fix was in solo/admin.py with the form_url parameter.

My full setup:

from solo.admin import SingletonModelAdmin
from reversion.admin import VersionAdmin

class MySingletonAdmin(SingletonModelAdmin):  # form_url param added
    def change_view(self, request, object_id, form_url='', extra_context=None):
        if object_id == '1':
            self.model.objects.get_or_create(pk=1)
        return super(SingletonModelAdmin, self).change_view(
            request,
            object_id,
            form_url=form_url,  # form_url param added
            extra_context=extra_context,
        )

class MyModelAdmin(VersionAdmin, MySingletonAdmin):
    pass

admin.site.register(Document, MyModelAdmin)

Now there's no need in changing reversion/admin.py. So I guess it is completely django-solo's issue.

Hmm, so that form_url parameter is part of the Django admin spec, so I guess it should be changed in django-solo.

However, by the looks of things, this was fixed in a recent commit, but not released to PyPi yet...

7d1c66e

@lazybird I confirm that latest master fixes above issue and django-reversion works without hacks. Can we get a pypi release?