django-reversion-compare coveralls travis-ci python

Add compare view to django-reversion for comparing two versions of a reversion model.

2 years after

= django-reversion-compare =

django-reversion-compare is an extension to [[https://github.com/etianen/django-reversion/|django-reversion]] that provides a history compare view to compare two versions of a model which is under reversion.

Comparing model versions is not a easy task. Maybe there are different view how this should looks like. This project will gives you a generic way to see whats has been changed.

Many parts are customizable by overwrite methods or subclassing, see above.

| {{https://coveralls.io/repos/jedie/django-reversion-compare/badge.svg|Coverage Status on coveralls.io}} | [[https://coveralls.io/r/jedie/django-reversion-compare|coveralls.io/r/jedie/django-reversion-compare]] | | {{https://travis-ci.org/jedie/django-reversion-compare.svg|Build Status on travis-ci.org}} | [[https://travis-ci.org/jedie/django-reversion-compare/|travis-ci.org/jedie/django-reversion-compare]] | | {{https://requires.io/github/jedie/django-reversion-compare/requirements.svg|Requirements Status on requires.io}} | [[https://requires.io/github/jedie/django-reversion-compare/requirements/|requires.io/github/jedie/django-reversion-compare/requirements/]] |

== Installation ==

Just use: {{{ pip install django-reversion-compare }}}

Optionally you can install [[https://code.google.com/p/google-diff-match-patch/|google-diff-match-patch]], otherwise difflib would be used. The easiest way is to use the unofficial package [[http://pypi.python.org/pypi/diff-match-patch/|diff-match-patch]], e.g.: {{{ pip install diff-match-patch }}}

=== Setup ===

Add reversion_compare to INSTALLED_APPS in your settings.py, e.g.: {{{ INSTALLED_APPS = ( 'django...', ... 'reversion', # https://github.com/etianen/django-reversion 'reversion_compare', # https://github.com/jedie/django-reversion-compare ... )

Add reversion models to admin interface:

ADD_REVERSION_ADMIN=True }}}

=== Usage ===

Inherit from CompareVersionAdmin instead of VersionAdmin to get the comparison feature.

admin.py e.g.: {{{ from django.contrib import admin from reversion_compare.admin import CompareVersionAdmin

from my_app.models import ExampleModel

class ExampleModelAdmin(CompareVersionAdmin): pass

admin.site.register(ExampleModel, ExampleModelAdmin) }}}

If you're using an existing third party app, then you can add patch django-reversion-compare into its admin class by using the reversion_compare.helpers.patch_admin() method. For example, to add version control to the built-in User model:

{{{ from reversion_compare.helpers import patch_admin

patch_admin(User) }}}

e.g.: Add django-cms Page model: {{{ from cms.models.pagemodel import Page from reversion_compare.helpers import patch_admin

Patch django-cms Page Model to add reversion-compare functionality:

patch_admin(Page) }}}

=== Customize ===

It's possible to change the look for every field or for a entire field type. You must only define a methods to your admin class with this name scheme:

  • {{{ "compare_%s" % field_name }}}
  • {{{ "compare_%s" % field.get_internal_type() }}}

If there is no method with this name scheme, the {{{ fallback_compare() }}} method will be used.

An example for specifying a compare method for a model field by name:

{{{ class YourAdmin(CompareVersionAdmin): def compare_foo_bar(self, obj_compare): """ compare the foo_bar model field """ return "%r <-> %r" % (obj_compare.value1, obj_compare.value2) }}}

and example using patch_admin with custom version admin class: {{{ patch_admin(User, AdminClass=YourAdmin) }}}

== Class Based View ==

Beyond the Admin views, you can also create a Class Based View for displaying and comparing version differences. This is a single class-based-view that either displays the list of versions to select for an object or displays both the versions and their differences (if the versions to be compared have been selected). This class can be used just like a normal DetailView:

Inherit from it in your class and add a model (or queryset), for example:

{{{ from reversion_compare.views import HistoryCompareDetailView

class SimpleModelHistoryCompareView(HistoryCompareDetailView): model = SimpleModel }}}

Then, assign that CBV to a url, for example:

{{{ url(r'^test_view/(?P\d+)$', views.SimpleModelHistoryCompareView.as_view() ), }}}

Last step, you need to create a template to display both the version select form and the changes part (if the form is submitted). An example template is the following:

{{{

{% include "reversion-compare/action_list_partial.html" %} {% if request.GET.version_id1 %} {% include "reversion-compare/compare_partial.html" %} {% include "reversion-compare/compare_links_partial.html" %} {% endif %} }}}

Beyond the styling, you should include:

  • reversion-compare/action_list_partial.html partial template to display the version select form
  • reversion-compare/compare_partial.html partial template to display the actual version
  • reversion-compare/compare_links_partial.html to include previous/next comparison links

compare_partial.html and compare_links_partial.html will show the compare-related information so it's better to display them only when the select-versions-tocompare-form has been submitted. If you want more control on the appearence of your templates you can check the above partials to understand how the availabble context variables are used and override them completely.

== Screenshots ==

Here some screenshots of django-reversion-compare:


How to select the versions to compare:

{{http://www.pylucid.org/static/pylucid.org/screenshots_PyLucid/django-reversion/django-reversion-compare_v0_1_0-01.png|django-reversion-compare_v0_1_0-01.png}}


from v0.1.0: DateTimeField compare (last update), TextField compare (content) with small changes and a ForeignKey compare (child model instance was added):

{{http://www.pylucid.org/static/pylucid.org/screenshots_PyLucid/django-reversion/django-reversion-compare_v0_1_0-02.png|django-reversion-compare_v0_1_0-02.png}}


from v0.1.0: Same as above, but the are more lines changed in TextField and the ForeignKey relation was removed:

{{http://www.pylucid.org/static/pylucid.org/screenshots_PyLucid/django-reversion/django-reversion-compare_v0_1_0-03.png|django-reversion-compare_v0_1_0-03.png}}


Example screenshot from v0.3.0: a many-to-many field compare (friends, hobbies):

{{http://www.pylucid.org/static/pylucid.org/screenshots_PyLucid/django-reversion/django-reversion-compare_v0_3_0-01.png|django-reversion-compare_v0_3_0-01.png}}

  • In the first line, the m2m object has been changed.
  • line 2: A m2m object was deleted
  • line 3: A m2m object was removed from this entry (but not deleted)
  • line 4: This m2m object has not changed

== Unittests ==

(Unittests need [[https://github.com/jedie/django-tools/|django-tools]])

=== Run unittests ===

via setup.py: {{{ $ cd path/to/django-reversion-compare django-reversion-compare$ ./setup.py test }}}

via runtests.py: {{{ $ cd path/to/django-reversion-compare django-reversion-compare$ ./runtests.py }}}

Helpfull for writing and debugging unittests is to run a local test server with the same data. e.g.: {{{ ~$ cd path/to/django-reversion-compare/ /django-reversion-compare$ ./run_testserver.py }}} migration will be run and a superuser will be created. Username: test Password: 12345678

== Version compatibility ==

|= Reversion-Compare |=django-reversion |= Django |= Python |>=v0.7.2 | v2.0 | v1.8, v1.9, v1.10 | v2.7, v3.4, v3.5 |v0.7.x | v2.0 | v1.8, v1.9 | v2.7, v3.4, v3.5 |v0.6.x | v1.9, v1.10 | v1.8, v1.9 | v2.7, v3.4, v3.5 |>=v0.5.2 | v1.9 | v1.7, v1.8 | v2.7, v3.4 |>=v0.4 | v1.8 | v1.7 | v2.7, v3.4 |<v0.4 | v1.6 | v1.4 | v2.7

These are the unittests variants. See also: [[https://github.com/jedie/django-reversion-compare/blob/master/.travis.yml|/.travis.yml]] Maybe other versions are compatible, too.

== Changelog ==

== Links ==

| IRC | [[http://www.pylucid.org/permalink/304/irc-channel|#pylucid on freenode.net]] | Github | [[http://github.com/jedie/django-reversion-compare]] | Python Packages | [[http://pypi.python.org/pypi/django-reversion-compare/]]

== Contact ==

Come into the conversation, besides the Github communication features:

| IRC | #pylucid on freenode.net (Yes, the PyLucid channel...) | webchat | http://webchat.freenode.net/?channels=pylucid

== Donation

Related Repositories

django-processinfo

django-processinfo

Django-app for collecting information from running django processes. ...


Top Contributors

etianen jedie etienned LegoStormtroopr spapas pahaz Jbonnett bmihelac frwickst gavinwahl mlavin adamchainz eliast vdboor luzfcb quantum5 yorkedork wuilliam321 zsiciarz shamrin SaeX Aikurn AndrewHows acdha EnTeQuAk jdnier flreinhard codingjoe fladi mshannon1123

Releases

-   v0.7.2 zip tar
-   v0.7.1 zip tar
-   v0.7.0 zip tar
-   v0.6.3 zip tar
-   v0.6.2 zip tar
-   v0.6.1 zip tar
-   v0.6.0 zip tar
-   v0.5.6 zip tar
-   v0.5.5 zip tar
-   v0.5.4 zip tar
-   v0.5.3 zip tar
-   v0.5.2 zip tar
-   v0.5.1 zip tar
-   v0.5.0 zip tar
-   v0.4.0 zip tar
-   django-reversion-com zip tar
-   django-reversion-com zip tar
-   django-reversion-com zip tar
-   django-reversion-com zip tar
-   django-reversion-com zip tar
-   django-reversion-com zip tar