history compare for django-reversion
Project description
django-reversion-compare is an extension to 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.
requires.io/github/jedie/django-reversion-compare/requirements/ |
Installation
Just use:
pip install django-reversion-compare
Optionally you can install google-diff-match-patch, otherwise difflib would be used. The easiest way is to use the unofficial package 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<pk>\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:
<style type="text/css"> /* minimal style for the diffs */ del, ins { color: #000; text-decoration: none; } del { background-color: #ffe6e6; } ins { background-color: #e6ffe6; } sup.follow { color: #5555ff; } </style> {% 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:
from v0.1.0: DateTimeField compare (last update), TextField compare (content) with small changes and a ForeignKey compare (child model instance was added):
from v0.1.0: Same as above, but the are more lines changed in TextField and the ForeignKey relation was removed:
Example screenshot from v0.3.0: a many-to-many field compare (friends, hobbies):
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
running tests
Run all tests in all environment combinations via tox:
$ python3 setup.py tox
Run all tests in current environment via pytest:
$ python3 setup.py test
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.8.4 |
v2.0 |
v1.8, v1.11, v2.0 |
v3.5, v3.6, pypy3 |
>=v0.8.3 |
v2.0 |
v1.8, v1.11 |
v3.5, v3.6, pypy3 |
v0.8.x |
v2.0 |
v1.8, v1.10, v1.11 |
v2.7, v3.4, v3.5, v3.6 (only with Django 1.11) |
>=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: /.travis.yml Maybe other versions are compatible, too.
Changelog
v0.8.4 - 15.03.2018 compare v0.8.3…v0.8.4
Add Django 2.0 compatibility contributed by samifahed
v0.8.3 - 21.12.2017 compare v0.8.2…v0.8.3
refactor travis/tox/pytest/coverage stuff
Tests can be run via python3 setup.py tox and/or python3 setup.py test
Test also with pypy3 on Travis CI.
-
Change ForeignKey relation compare contributed by alaruss
Work around a type error triggered by taggit contributed by Athemis
minor code changes
-
Add added polish translation contributed by w4rri0r3k
Bugfix “Django>=1.11” in setup.py
-
Run tests with Django v1.11 and drop tests with Django v1.9
-
-
Bugfix for Python 2: compare unicode instead of bytes contributed by Maksim Iakovlev
remove ‘Django20Warning’ contributed by Hugo Tácito
Add ‘Finnish’ localisations contributed by Olli-Pekka Puolitaival
-
-
Add Django v1.10 support
-
-
support only django-reversion >= 2.0 based on a contribution by mshannon1123
remove internal reversion_api
Use tox
-
Remove unused and deprecated patters contributed by codingjoe
Fix django 1.10 warning #66 contributed by pypetey
-
Added choices field representation #63 contributed by amureki
Check if related model has an integer as pk for ManyToMany fields. #64 contributed by logaritmisk
-
pull #61: Fix error when ManyToMany relations didn’t exist contributed by Diederik van der Boor
-
Added Dutch translation contributed by Sae X
Add support for Django 1.9
Nicer boolean compare: #57
Fix #58 compare followed reverse foreign relation fields that are on a non-abstract parent class contributed by LegoStormtroopr
-
NEW: Class-Based-View to create non-admin views and greek translation contributed by Serafeim Papastefanos.
-
UnboundLocalError (‘version’) when creating deleted list in get_many_to_something() #41
-
One to one field custom related name fix #42 (contributed by frwickst and aemdy)
-
Update admin.py to avoid RemovedInDjango19Warning (contributed by luzfcb)
-
contributed by Samuel Spencer:
Added Django 1.8 support: pull #35
list of changes for reverse fields incorrectly includes a “deletion” for the item that was added in: issues #34
-
activate previous/next links and add unitests for them
-
refactory unittests, test with Django v1.7 and Python 2.7 & 3.4
-
Updates for django 1.7 support
Add settings.ADD_REVERSION_ADMIN
v0.3.5 - 03.01.2013:
Remove date from version string. issues 9
v0.3.4 - 20.06.2012:
Use VersionAdmin.revision_manager rather than default_revision_manager, contributed by Mark Lavin - see: pull request 7
Use logging for all debug prints, contributed by Bojan Mihelac - see: pull request 8
v0.3.3 - 11.06.2012:
Bugfix “ValueError: zero length field name in format” with Python 2.6 issues 5
v0.3.2 - 04.06.2012:
Bugfix for Python 2.6 in unified_diff(), see: AttributeError: ‘module’ object has no attribute ‘_format_range_unified’
v0.3.1 - 01.06.2012:
Bugfix: force unicode in html diff
Bugfix in unittests
v0.3.0 - 16.05.2012:
Enhanced handling of m2m changes with follow and non-follow relations.
v0.2.2 - 15.05.2012:
Compare many-to-many in the right way.
v0.2.1 - 10.05.2012:
Bugfix for models which has no m2m field: https://github.com/jedie/django-reversion-compare/commit/c8e042945a6e78e5540b6ae27666f9b0cfc94880
v0.2.0 - 09.05.2012:
many-to-many compare works, too.
v0.1.0 - 08.05.2012:
First release
v0.0.1 - 08.05.2012:
collect all compare stuff from old “diff” branch
see also: https://github.com/etianen/django-reversion/issues/147
Links
Github |
|
Python Packages |
https://pypi-hypernode.com/project/django-reversion-compare/ |
Donation
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for django-reversion-compare-0.8.4.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0bf01276e3cd595b4e71d7de6692d48345adc0baec766d7920353b4448349654 |
|
MD5 | 702a336511c1215d2351bf46fd86a3c1 |
|
BLAKE2b-256 | 3b29c629c3360e8863144c910b04ff1b23fb5ce88a5279f5fe403a464180cd56 |
Hashes for django_reversion_compare-0.8.4-py3.6.egg
Algorithm | Hash digest | |
---|---|---|
SHA256 | c902cfa2acddaf02e736139415cf31deee673d8f1b8c15ec6e05c04889dddabf |
|
MD5 | 9b385193a2ba51ce54565a45a43689cf |
|
BLAKE2b-256 | c8bf812647bc5552f22f23ad6c47d1b0b5da7970954fd8c6afd421a1b2bfe86b |
Hashes for django_reversion_compare-0.8.4-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ba1061e29f5c40f513629b2613cacd5f879ffaba44743c0e4e4e4908f5b6d3d2 |
|
MD5 | 9f4620f0ac4da1745f647db25660efb9 |
|
BLAKE2b-256 | 4ccc6225519d87e9eb3c3b400bcfd86967a5934d379a4aa395262a24e5163ac2 |