From 62699eab16008ba20233668294b5ae5258b9eec7 Mon Sep 17 00:00:00 2001
From: Michael Shannon 
Date: Thu, 18 Aug 2016 08:48:52 -0400
Subject: [PATCH] Update for django-reversion 2.0
---
 .travis.yml                              |   4 +-
 AUTHORS                                  |   2 +
 reversion_compare/admin.py               |  12 +-
 reversion_compare/compare.py             | 283 ++++++++++-------------
 reversion_compare/forms.py               |   1 +
 reversion_compare/helpers.py             |   5 +-
 reversion_compare/mixins.py              |  21 +-
 reversion_compare/reversion_api.py       |  27 ++-
 reversion_compare/views.py               |   8 +-
 setup.py                                 |   7 -
 tests/admin.py                           |  13 +-
 tests/models.py                          |  20 +-
 tests/test_custom_model.py               |  28 +--
 tests/test_factory_car_models.py         |  47 ++--
 tests/test_factory_car_reverse_models.py |  23 +-
 tests/test_onetoone_field.py             |  17 +-
 tests/test_person_pet_models.py          |  72 +++---
 tests/test_settings.py                   |   6 +-
 tests/test_simple_model.py               |  54 ++---
 tests/test_utils/test_cases.py           |  14 +-
 tests/test_utils/test_data.py            |  19 +-
 tests/test_variant_model.py              |  16 +-
 tests/test_view.py                       |  45 ++--
 tests/views.py                           |   2 +-
 24 files changed, 348 insertions(+), 398 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index ca5198af..69fc037f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,9 +12,11 @@ env:
     - DJANGO='1.8' REVERSION='1.9'  EXTRA=''
     - DJANGO='1.8' REVERSION='1.10' EXTRA=''
     - DJANGO='1.9' REVERSION='1.10' EXTRA=''
+    - DJANGO='1.9' REVERSION='2.0' EXTRA=''
     - DJANGO='1.8' REVERSION='1.9'  EXTRA='diff-match-patch'
-    - DJANGO='1.8' REVERSION='1.10'  EXTRA='diff-match-patch'
+    - DJANGO='1.8' REVERSION='1.10' EXTRA='diff-match-patch'
     - DJANGO='1.9' REVERSION='1.10' EXTRA='diff-match-patch'
+    - DJANGO='1.9' REVERSION='2.0' EXTRA='diff-match-patch'
 
 install:
     - pip install --upgrade pip
diff --git a/AUTHORS b/AUTHORS
index 3822f061..dfddd840 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -33,6 +33,8 @@ CONTRIBUTORS are and/or have been (alphabetic order):
   Github: 
 * Spencer, Samuel
   Github: 
+* Shannon, Michael
+  Github: 
 * C. Barrionuevo da Luz, Fabio
   Github: 
 * Wickström, Frank
diff --git a/reversion_compare/admin.py b/reversion_compare/admin.py
index 5717f6b5..2a022924 100644
--- a/reversion_compare/admin.py
+++ b/reversion_compare/admin.py
@@ -20,7 +20,7 @@
 from django.contrib import admin
 try:
     from django.contrib.admin.utils import unquote, quote
-except ImportError:  # Django < 1.7
+except ImportError:  # Django < 1.7  # pragma: no cover
     from django.contrib.admin.util import unquote, quote
 from django.core.urlresolvers import reverse
 from django.http import Http404
@@ -29,12 +29,12 @@
 from django.utils.translation import ugettext as _
 
 try:
-    from reversion import revisions as reversion # django-reversion >= 1.10
+    from reversion import revisions as reversion  # django-reversion >= 1.10
 except ImportError:
-    import reversion # django-reversion <= 1.9
+    import reversion  # django-reversion <= 1.9
 
 from reversion.admin import VersionAdmin
-
+from reversion_compare import reversion_api
 from reversion_compare.forms import SelectDiffForm
 from reversion_compare.mixins import CompareMixin, CompareMethodsMixin
 
@@ -111,7 +111,7 @@ def _get_action_list(self, request, object_id, extra_context=None):
                                args=(quote(version.object_id), version.id)),
             }
             for version
-            in self._order_version_queryset(self.revision_manager.get_for_object_reference(
+            in self._order_version_queryset(reversion_api.get_for_object_reference(
                 self.model,
                 object_id,
             ).select_related("revision__user"))
@@ -168,7 +168,7 @@ def compare_view(self, request, object_id, extra_context=None):
 
         object_id = unquote(object_id)  # Underscores in primary key get quoted to "_5F"
         obj = get_object_or_404(self.model, pk=object_id)
-        queryset = self.revision_manager.get_for_object(obj)
+        queryset = reversion_api.get_for_object(obj)
         version1 = get_object_or_404(queryset, pk=version_id1)
         version2 = get_object_or_404(queryset, pk=version_id2)
 
diff --git a/reversion_compare/compare.py b/reversion_compare/compare.py
index ea470ee9..39dcff0b 100644
--- a/reversion_compare/compare.py
+++ b/reversion_compare/compare.py
@@ -16,11 +16,8 @@
 from django.db import models
 from django.utils.encoding import force_text, python_2_unicode_compatible
 from django.utils.translation import ugettext as _
-
-
 from reversion_compare import reversion_api
 
-
 logger = logging.getLogger(__name__)
 
 
@@ -36,21 +33,21 @@ def __str__(self):
 
 
 class CompareObject(object):
-    def __init__(self, field, field_name, obj, version, has_int_pk, adapter):
+
+    def __init__(self, field, field_name, obj, version_record, follow):
         self.field = field
         self.field_name = field_name
         self.obj = obj
-        self.version = version  # instance of reversion.models.Version()
-        self.has_int_pk = has_int_pk
-        self.adapter = adapter
+        self.version_record = version_record  # instance of reversion.models.Version()
+        self.follow = follow
         # try and get a value, if none punt
-        self.value = version.field_dict.get(field_name, DOES_NOT_EXIST)
+        self.value = version_record.field_dict.get(field_name, DOES_NOT_EXIST)
 
     def _obj_repr(self, obj):
         # FIXME: How to create a better representation of the current value?
         try:
             return str(obj)
-        except Exception as e:
+        except Exception:
             return repr(obj)
 
     def _choices_repr(self, obj):
@@ -58,12 +55,10 @@ def _choices_repr(self, obj):
                           strings_only=True)
 
     def _to_string_ManyToManyField(self):
-        queryset = self.get_many_to_many()
-        return ", ".join([self._obj_repr(item) for item in queryset])
+        return ", ".join([self._obj_repr(item) for item in self.get_many_to_many()])
 
     def _to_string_ForeignKey(self):
-        obj = self.get_related()
-        return self._obj_repr(obj)
+        return self._obj_repr(self.get_related())
 
     def to_string(self):
         internal_type = self.field.get_internal_type()
@@ -91,9 +86,9 @@ def __eq__(self, other):
             return False
         
         # see - https://hynek.me/articles/hasattr/
-        internal_type = getattr(self.field,'get_internal_type',None)
+        internal_type = getattr(self.field, 'get_internal_type', None)
         if internal_type is None or internal_type() == "ForeignKey":  # FIXME!
-            if self.version.field_dict != other.version.field_dict:
+            if self.version_record.field_dict != other.version_record.field_dict:
                 return False
 
         return True
@@ -101,35 +96,46 @@ def __eq__(self, other):
     def __ne__(self, other):
         return not self.__eq__(other)
 
+    def get_object_version(self):
+        if hasattr(self.version_record, '_object_version'):
+            return getattr(self.version_record, '_object_version')
+        else:
+            return getattr(self.version_record, 'object_version')
+
     def get_related(self):
         if getattr(self.field, 'rel', None):
-            obj = self.version.object_version.object
+            obj = self.get_object_version().object
             try:
                 return getattr(obj, self.field.name, None)
             except ObjectDoesNotExist:
                 return None
 
     def get_reverse_foreign_key(self):
-        obj = self.version.object_version.object
-        if self.has_int_pk and self.field.related_name and hasattr(obj, self.field.related_name):
+        obj = self.get_object_version().object
+        if self.field.related_name and hasattr(obj, self.field.related_name):
             if isinstance(self.field, models.fields.related.OneToOneRel):
                 try:
-                    ids = [getattr(obj, str(self.field.related_name)).pk]
+                    ids = {force_text(getattr(obj, str(self.field.related_name)).pk), }
                 except ObjectDoesNotExist:
-                    ids = []
+                    ids = set()
             else:
-                ids = [v.id for v in getattr(obj, str(self.field.related_name)).all()]  # is: version.field_dict[field.name]
-                if ids == [] and any([f.name.endswith('_ptr') for f in obj._meta.fields]):
-                    # If there is a _ptr this is a multiinheritance table and inherits from a non-abstract class
+                # If there is a _ptr this is a multi-inheritance table and inherits from a non-abstract class
+                ids = {force_text(v.id) for v in getattr(obj, str(self.field.related_name)).all()}
+                if not ids and any([f.name.endswith('_ptr') for f in obj._meta.get_fields()]):
+                    # If there is a _ptr this is a multi-inheritance table and inherits from a non-abstract class
                     # lets try and get the parent items associated entries for this field
-                    others = self.version.revision.version_set.filter(object_id=self.version.object_id)
+                    others = self.version_record.revision.version_set.filter(
+                        object_id=self.version_record.object_id
+                    ).all()
                     for p in others:
-                        p_obj = p.object_version.object
-                        if type(p_obj) != type(obj) and hasattr(p_obj,str(self.field.related_name)):
-                            ids = [v.id for v in getattr(p_obj, str(self.field.related_name)).all()]
-
+                        if hasattr(p, '_object_version'):
+                            p_obj = getattr(p, '_object_version').object
+                        else:
+                            p_obj = getattr(p, 'object_version').object
+                        if type(p_obj) != type(obj) and hasattr(p_obj, str(self.field.related_name)):
+                            ids = {force_text(v.id) for v in getattr(p_obj, str(self.field.related_name)).all()}
         else:
-            return ([], [], [], [])  # TODO: refactory that
+            return {}, {}, []  # TODO: refactor that
 
         # Get the related model of the current field:
         related_model = self.field.field.model
@@ -140,66 +146,55 @@ def get_many_to_many(self):
         returns a queryset with all many2many objects
         """
         if self.field.get_internal_type() != "ManyToManyField":  # FIXME!
-            return ([], [], [], [])  # TODO: refactory that
+            return {}, {}, []  # TODO: refactor that
         elif self.value is DOES_NOT_EXIST:
-            return ([], [], [], [])  # TODO: refactory that
-
-        related_model = self.field.rel.to
+            return {}, {}, []  # TODO: refactor that
 
-        ids = None
-        if reversion_api.has_int_pk(related_model):
-            ids = [int(v) for v in self.value]  # is: version.field_dict[field.name]
+        ids = frozenset(map(force_text, self.value))
 
         # Get the related model of the current field:
-        return self.get_many_to_something(ids, related_model)
-
-    def get_many_to_something(self, ids, related_model, is_reverse=False):
+        return self.get_many_to_something(ids, self.field.rel.to)
 
+    def get_many_to_something(self, target_ids, related_model, is_reverse=False):
         # get instance of reversion.models.Revision():
         # A group of related object versions.
-        old_revision = self.version.revision
+        old_revision = self.version_record.revision
 
         # Get a queryset with all related objects.
-        versions = old_revision.version_set.filter(
-            content_type=ContentType.objects.get_for_model(related_model),
-            object_id__in=ids
-        )
-
-        if self.has_int_pk:
-            # The primary_keys would be stored in a text field -> convert it to integers
-            # This is interesting in different places!
-            for version in versions:
-                version.object_id = int(version.object_id)
+        versions = {
+            ver.object_id: ver for ver in old_revision.version_set.filter(
+                content_type=ContentType.objects.get_for_model(related_model),
+                object_id__in=target_ids
+            ).all()
+        }
 
-        missing_objects = []
-        missing_ids = []
+        missing_objects_dict = {}
+        deleted = []
 
-        if self.field_name not in self.adapter.follow:
+        if not self.follow:
             # This models was not registered with follow relations
             # Try to fill missing related objects
-            target_ids = set(ids)
-            actual_ids = set([version.object_id for version in versions])
-            missing_ids1 = target_ids.difference(actual_ids)
-
-            # logger.debug(self.field_name, "target: %s - actual: %s - missing: %s" % (target_ids, actual_ids, missing_ids1))
-            if missing_ids1:
-                missing_objects = related_model.objects.all().filter(pk__in=missing_ids1)
-                missing_ids = list(target_ids.difference(set(missing_objects.values_list('pk', flat=True))))
+            potentially_missing_ids = target_ids.difference(frozenset(versions))
+            # logger.debug(self.field_name, "target: %s - actual: %s - missing: %s" % (target_ids, versions, potentially_missing_ids))
+            if potentially_missing_ids:
+                missing_objects_dict = {
+                    force_text(rel.pk): rel
+                    for rel in related_model.objects.filter(pk__in=potentially_missing_ids).iterator()
+                }
 
-        deleted = []
         if is_reverse:
-            true_missing_objects = []
-            for o in missing_objects:
-                for ver in reversion_api.get_for_object(o):
-                    # An object can only be missing if it actually existed prior to this version
-                    # Otherwise its a new item
-                    if ver.revision.date_created < old_revision.date_created:
-                        true_missing_objects.append(o)
-            missing_objects = true_missing_objects
+            missing_objects_dict = {
+                ver.object_id: ver
+                for o in missing_objects_dict.values()
+                for ver in reversion_api.get_for_object(o)
+                if ver.revision.date_created < old_revision.date_created
+            }
+
             deleted = [d for d in reversion_api.get_deleted(related_model) if d.revision == old_revision]
-        return versions, missing_objects, missing_ids, deleted
 
-    def get_debug(self):
+        return versions, missing_objects_dict, deleted
+
+    def get_debug(self):  # pragma: no cover
         if not settings.DEBUG:
             return
 
@@ -207,11 +202,9 @@ def get_debug(self):
             "field..............: %r" % self.field,
             "field_name.........: %r" % self.field_name,
             "field internal type: %r" % self.field.get_internal_type(),
-            "field_dict.........: %s" % repr(self.version.field_dict),
-            "adapter............: %r (follow: %r)" % (self.adapter, ", ".join(self.adapter.follow)),
-            "has_int_pk ........: %r" % self.has_int_pk,
+            "field_dict.........: %s" % repr(self.version_record.field_dict),
             "obj................: %r (pk: %s, id: %s)" % (self.obj, self.obj.pk, id(self.obj)),
-            "version............: %r (pk: %s, id: %s)" % (self.version, self.version.pk, id(self.version)),
+            "version............: %r (pk: %s, id: %s)" % (self.version_record, self.version_record.pk, id(self.version_record)),
             "value..............: %r" % self.value,
             "to string..........: %s" % repr(self.to_string()),
             "related............: %s" % repr(self.get_related()),
@@ -220,12 +213,12 @@ def get_debug(self):
         if m2m_versions or missing_objects or missing_ids:
             result.append(
                 "many-to-many.......: %s" % ", ".join(
-                    ["%s (%s)" % (
-                        item,
-                        item.type
-                    ) for item in m2m_versions]
+                        ["%s (%s)" % (
+                            item,
+                            item.type
+                        ) for item in m2m_versions]
+                    )
                 )
-            )
 
             if missing_objects:
                 result.append("missing m2m objects: %s" % repr(missing_objects))
@@ -241,7 +234,7 @@ def get_debug(self):
 
         return result
 
-    def debug(self):
+    def debug(self):  # pragma: no cover
         if not settings.DEBUG:
             return
         for item in self.get_debug():
@@ -249,31 +242,30 @@ def debug(self):
 
 
 class CompareObjects(object):
-    def __init__(self, field, field_name, obj, version1, version2, manager, is_reversed):
+    def __init__(self, field, field_name, obj, version1, version2, is_reversed):
         self.field = field
         self.field_name = field_name
         self.obj = obj
 
-        model = self.obj.__class__
-        self.has_int_pk = reversion_api.has_int_pk(model)
-        self.adapter = manager.get_adapter(model)  # VersionAdapter instance
-
         # is a related field (ForeignKey, ManyToManyField etc.)
         self.is_related = getattr(self.field, 'rel', None) is not None
         self.is_reversed = is_reversed
         if not self.is_related:
             self.follow = None
-        elif self.field_name in self.adapter.follow:
+        elif self.field_name in reversion_api._get_options(self.obj.__class__).follow:
             self.follow = True
         else:
             self.follow = False
 
-        self.compare_obj1 = CompareObject(field, field_name, obj, version1, self.has_int_pk, self.adapter)
-        self.compare_obj2 = CompareObject(field, field_name, obj, version2, self.has_int_pk, self.adapter)
+        self.compare_obj1 = CompareObject(field, field_name, obj, version1, self.follow)
+        self.compare_obj2 = CompareObject(field, field_name, obj, version2, self.follow)
 
         self.value1 = self.compare_obj1.value
         self.value2 = self.compare_obj2.value
 
+        self.M2O_CHANGE_INFO = None
+        self.M2M_CHANGE_INFO = None
+
     def changed(self):
         """ return True if at least one field has changed values. """
 
@@ -294,31 +286,17 @@ def changed(self):
 
         return self.compare_obj1 != self.compare_obj2
 
-    def _get_result(self, compare_obj, func_name):
-        func = getattr(compare_obj, func_name)
-        result = func()
-        return result
-
-    def _get_both_results(self, func_name):
-        result1 = self._get_result(self.compare_obj1, func_name)
-        result2 = self._get_result(self.compare_obj2, func_name)
-        return (result1, result2)
-
     def to_string(self):
-        return self._get_both_results("to_string")
+        return self.compare_obj1.to_string(), self.compare_obj2.to_string()
 
     def get_related(self):
-        return self._get_both_results("get_related")
+        return self.compare_obj1.get_related(), self.compare_obj2.get_related()
 
     def get_many_to_many(self):
-        # return self._get_both_results("get_many_to_many")
-        m2m_data1, m2m_data2 = self._get_both_results("get_many_to_many")
-        return m2m_data1, m2m_data2
+        return self.compare_obj1.get_many_to_many(), self.compare_obj2.get_many_to_many()
 
     def get_reverse_foreign_key(self):
-        return self._get_both_results("get_reverse_foreign_key")
-
-    M2O_CHANGE_INFO = None
+        return self.compare_obj1.get_reverse_foreign_key(), self.compare_obj2.get_reverse_foreign_key()
 
     def get_m2o_change_info(self):
         if self.M2O_CHANGE_INFO is not None:
@@ -329,8 +307,6 @@ def get_m2o_change_info(self):
         self.M2O_CHANGE_INFO = self.get_m2s_change_info(m2o_data1, m2o_data2)
         return self.M2O_CHANGE_INFO
 
-    M2M_CHANGE_INFO = None
-
     def get_m2m_change_info(self):
         if self.M2M_CHANGE_INFO is not None:
             return self.M2M_CHANGE_INFO
@@ -341,51 +317,39 @@ def get_m2m_change_info(self):
         return self.M2M_CHANGE_INFO
 
     # Abstract Many-to-Something (either -many or -one) as both
-    # many2many and many2one relationships looks the same from the refered object.
+    # many2many and many2one relationships looks the same from the referred object.
     def get_m2s_change_info(self, obj1_data, obj2_data):
 
-        result1, missing_objects1, missing_ids1, deleted1 = obj1_data
-        result2, missing_objects2, missing_ids2, deleted2 = obj2_data
-
-        # missing_objects_pk1 = [obj.pk for obj in missing_objects1]
-        #        missing_objects_pk2 = [obj.pk for obj in missing_objects2]
-        missing_objects_dict2 = dict([(obj.pk, obj) for obj in missing_objects2])
-
-        # logger.debug("missing_objects1: %s", missing_objects1)
-        # logger.debug("missing_objects2: %s", missing_objects2)
-        # logger.debug("missing_ids1: %s", missing_ids1)
-        # logger.debug("missing_ids2: %s", missing_ids2)
-
-        missing_object_set1 = set(missing_objects1)
-        missing_object_set2 = set(missing_objects2)
-        # logger.debug("%s %s", missing_object_set1, missing_object_set2)
-
-        same_missing_objects = missing_object_set1.intersection(missing_object_set2)
-        removed_missing_objects = missing_object_set1.difference(missing_object_set2)
-        added_missing_objects = missing_object_set2.difference(missing_object_set1)
-
-        # logger.debug("same_missing_objects: %s", same_missing_objects)
-        # logger.debug("removed_missing_objects: %s", removed_missing_objects)
-        # logger.debug("added_missing_objects: %s", added_missing_objects)
-
+        result_dict1, missing_objects_dict1, deleted1 = obj1_data
+        result_dict2, missing_objects_dict2, deleted2 = obj2_data
 
         # Create same_items, removed_items, added_items with related m2m items
-
         changed_items = []
         removed_items = []
         added_items = []
         same_items = []
 
-        primary_keys1 = [version.object_id for version in result1]
-        primary_keys2 = [version.object_id for version in result2]
-
-        result_dict1 = dict([(version.object_id, version) for version in result1])
-        result_dict2 = dict([(version.object_id, version) for version in result2])
+        same_missing_objects_dict = {
+            k: v for k, v in
+            missing_objects_dict1.items()
+            if k in missing_objects_dict2
+        }
+        removed_missing_objects_dict = {
+            k: v for k, v in
+            missing_objects_dict1.items()
+            if k not in missing_objects_dict2
+        }
+        added_missing_objects_dict = {
+            k: v for k, v in
+            missing_objects_dict2.items()
+            if k not in missing_objects_dict1
+        }
 
-        # logger.debug(result_dict1)
-        # logger.debug(result_dict2)
+        # logger.debug("same_missing_objects: %s", same_missing_objects_dict)
+        # logger.debug("removed_missing_objects: %s", removed_missing_objects_dict)
+        # logger.debug("added_missing_objects: %s", added_missing_objects_dict)
 
-        for primary_key in set(primary_keys1).union(set(primary_keys2)):
+        for primary_key in set().union(result_dict1.keys(), result_dict2.keys()):
             if primary_key in result_dict1:
                 version1 = result_dict1[primary_key]
             else:
@@ -396,33 +360,40 @@ def get_m2s_change_info(self, obj1_data, obj2_data):
             else:
                 version2 = None
 
-            #logger.debug("%r - %r - %r", primary_key, version1, version2)
+            # logger.debug("%r - %r - %r", primary_key, version1, version2)
 
             if version1 is not None and version2 is not None:
                 # In both -> version changed or the same
                 if version1.serialized_data == version2.serialized_data:
-                    #logger.debug("same item: %s", version1)
+                    # logger.debug("same item: %s", version1)
                     same_items.append(version1)
                 else:
                     changed_items.append((version1, version2))
             elif version1 is not None and version2 is None:
                 # In 1 but not in 2 -> removed
-                #logger.debug("%s %s", primary_key, missing_objects_pk2)
-                #logger.debug("%s %s", repr(primary_key), repr(missing_objects_pk2))
-                if primary_key in missing_objects_dict2:
-                    missing_object = missing_objects_dict2[primary_key]
-                    added_missing_objects.remove(missing_object)
-                    same_missing_objects.add(missing_object)
+                # logger.debug("%s %s", primary_key, missing_objects_dict2)
+                # logger.debug("%s %s", repr(primary_key), repr(missing_objects_dict2))
+                if primary_key in added_missing_objects_dict:
+                    added_missing_objects_dict.pop(primary_key)
+                    same_missing_objects_dict[primary_key] = missing_objects_dict2[primary_key]
                     continue
-
                 removed_items.append(version1)
             elif version1 is None and version2 is not None:
                 # In 2 but not in 1 -> added
-                #logger.debug("added: %s", version2)
+                # logger.debug("added: %s", version2)
                 added_items.append(version2)
             else:
                 raise RuntimeError()
 
+        # In Place Sorting of Lists (exclude changed since its a tuple)
+        removed_items.sort(key=lambda item: str(item))
+        added_items.sort(key=lambda item: str(item))
+        same_items.sort(key=lambda item: str(item))
+        deleted1.sort(key=lambda item: str(item))
+        same_missing_objects = sorted(same_missing_objects_dict.values(), key=lambda item: str(item))
+        removed_missing_objects = sorted(removed_missing_objects_dict.values(), key=lambda item: str(item))
+        added_missing_objects = sorted(added_missing_objects_dict.values(), key=lambda item: str(item))
+
         return {
             "changed_items": changed_items,
             "removed_items": removed_items,
@@ -434,8 +405,7 @@ def get_m2s_change_info(self, obj1_data, obj2_data):
             "deleted_items": deleted1,
         }
 
-
-    def debug(self):
+    def debug(self):  # pragma: no cover
         if not settings.DEBUG:
             return
         logger.debug("_______________________________")
@@ -469,4 +439,3 @@ def debug(self):
                 logger.debug(item)
 
         logger.debug("-" * 79)
-
diff --git a/reversion_compare/forms.py b/reversion_compare/forms.py
index f80b51bc..d9471c79 100644
--- a/reversion_compare/forms.py
+++ b/reversion_compare/forms.py
@@ -2,6 +2,7 @@
 
 from django import forms
 
+
 class SelectDiffForm(forms.Form):
     version_id1 = forms.IntegerField(min_value=1)
     version_id2 = forms.IntegerField(min_value=1)
diff --git a/reversion_compare/helpers.py b/reversion_compare/helpers.py
index 8df0f84e..dfd3561d 100644
--- a/reversion_compare/helpers.py
+++ b/reversion_compare/helpers.py
@@ -15,7 +15,6 @@
     :license: GNU GPL v3 or above, see LICENSE for more details.
 """
 
-
 import difflib
 import logging
 
@@ -38,7 +37,6 @@
 else:
     google_diff_match_patch = True
     dmp = diff_match_patch()
-#google_diff_match_patch = False # manually disable, for testing
 
 
 def highlight_diff(diff_text):
@@ -220,10 +218,9 @@ class PatchedModelAdmin(AdminClass, ModelAdmin):
     admin_site.register(model, PatchedModelAdmin)
 
 
-
 if __name__ == "__main__":
     import doctest
     print(doctest.testmod(
-#        verbose=True
         verbose=False
+        # verbose=True
     ))
diff --git a/reversion_compare/mixins.py b/reversion_compare/mixins.py
index c69748f5..98b54f3f 100644
--- a/reversion_compare/mixins.py
+++ b/reversion_compare/mixins.py
@@ -12,14 +12,12 @@
 from django.template.loader import render_to_string
 
 from reversion_compare.helpers import html_diff
-from reversion.revisions import default_revision_manager
-
 from reversion_compare.compare import CompareObjects
 
+
 class CompareMixin(object, ):
     """A mixin to add comparison capabilities to your views"""
-    
-    revision_manager = default_revision_manager
+
     # list/tuple of field names for the compare view. Set to None for all existing fields
     compare_fields = None
 
@@ -45,8 +43,8 @@ def _get_compare(self, obj_compare):
         """
 
         def _get_compare_func(suffix):
-            func_name = "compare_%s" % suffix
             # logger.debug("func_name: %s", func_name)
+            func_name = "compare_%s" % suffix
             if hasattr(self, func_name):
                 func = getattr(self, func_name)
                 return func
@@ -102,7 +100,7 @@ def compare(self, obj, version1, version2):
             )
             if isinstance(f, models.ForeignKey) and f not in fields:
                 self.reverse_fields.append(f.rel)
-        #print(self.reverse_fields)
+
         fields += self.reverse_fields
 
         has_unfollowed_fields = False
@@ -121,8 +119,8 @@ def compare(self, obj, version1, version2):
                 continue
 
             is_reversed = field in self.reverse_fields
-            obj_compare = CompareObjects(field, field_name, obj, version1, version2, self.revision_manager, is_reversed)
-            #obj_compare.debug()
+            obj_compare = CompareObjects(field, field_name, obj, version1, version2, is_reversed)
+            # obj_compare.debug()
 
             is_related = obj_compare.is_related
             follow = obj_compare.follow
@@ -171,9 +169,8 @@ def generic_add_remove(self, raw_value1, raw_value2, value1, value2):
 
     def compare_ForeignKey(self, obj_compare):
         related1, related2 = obj_compare.get_related()
-        obj_compare.debug()
+        # obj_compare.debug()
         value1, value2 = str(related1), str(related2)
-        # value1, value2 = repr(related1), repr(related2)
         return self.generic_add_remove(related1, related2, value1, value2)
 
     def simple_compare_ManyToManyField(self, obj_compare):
@@ -215,7 +212,7 @@ def compare_FileField(self, obj_compare):
         return self.generic_add_remove(value1, value2, value1, value2)
 
     def compare_DateTimeField(self, obj_compare):
-        ''' compare all model datetime field in ISO format '''
+        """ compare all model datetime field in ISO format """
         context = {
             "date1": obj_compare.value1,
             "date2": obj_compare.value2,
@@ -223,7 +220,7 @@ def compare_DateTimeField(self, obj_compare):
         return render_to_string("reversion-compare/compare_DateTimeField.html", context)
 
     def compare_BooleanField(self, obj_compare):
-        ''' compare booleans as a complete field, rather than as a string '''
+        """ compare booleans as a complete field, rather than as a string """
         context = {
             "bool1": obj_compare.value1,
             "bool2": obj_compare.value2,
diff --git a/reversion_compare/reversion_api.py b/reversion_compare/reversion_api.py
index 2bfe2abb..545093ac 100644
--- a/reversion_compare/reversion_api.py
+++ b/reversion_compare/reversion_api.py
@@ -1,19 +1,30 @@
-
 import reversion
-if reversion.__version__ > (1,10):
+from reversion.models import Revision, Version
+
+if reversion.__version__ > (2, 0):
     from reversion import revisions as reversion
     from reversion.revisions import (
         register, unregister, is_registered,
-        get_for_object, get_registered_models, get_deleted,
-        create_revision, set_comment
+        get_registered_models,
+        create_revision, set_comment, _get_options
     )
+    get_for_object_reference = Version.objects.get_for_object_reference
+    get_for_object = Version.objects.get_for_object
+    get_deleted = Version.objects.get_deleted
+elif reversion.__version__ > (1, 10):
+    from reversion import revisions as reversion
+    from reversion.revisions import (
+        register, unregister, is_registered,
+        get_for_object, get_for_object_reference, get_registered_models, get_deleted,
+        create_revision, set_comment, default_revision_manager
+    )
+    _get_options = default_revision_manager.get_adapter
 else:
     # django-reversion <= 1.9
     from reversion import (
         register, unregister, is_registered,
-        get_for_object, get_registered_models, get_deleted,
-        create_revision, set_comment
+        get_for_object, get_for_object_reference, get_registered_models, get_deleted,
+        create_revision, set_comment, default_revision_manager
     )
+    _get_options = default_revision_manager.get_adapter
 
-
-from reversion.models import Revision, Version, has_int_pk
\ No newline at end of file
diff --git a/reversion_compare/views.py b/reversion_compare/views.py
index 754b7ed3..7f181f3b 100644
--- a/reversion_compare/views.py
+++ b/reversion_compare/views.py
@@ -2,9 +2,11 @@
 from django.shortcuts import get_object_or_404
 from django.views.generic.detail import DetailView
 
+from reversion_compare import reversion_api
 from reversion_compare.forms import SelectDiffForm
 from reversion_compare.mixins import CompareMixin, CompareMethodsMixin
 
+
 class HistoryCompareDetailView(CompareMixin, CompareMethodsMixin, DetailView):
     """This class can be used to add a non-admin view for comparing your object's versions.
     
@@ -49,14 +51,13 @@ class SimpleModelHistoryCompareView(HistoryCompareDetailView):
     """
     
     def _get_action_list(self, ):
-        opts = self.model._meta
         action_list = [
             {
                 "version": version,
                 "revision": version.revision,
             }
             for version
-            in self._order_version_queryset(self.revision_manager.get_for_object(
+            in self._order_version_queryset(reversion_api.get_for_object(
                 self.get_object(),
             ).select_related("revision__user"))
         ]
@@ -93,7 +94,7 @@ def get_context_data(self, **kwargs):
                 version_id1, version_id2 = version_id2, version_id1
 
             obj = self.get_object()
-            queryset = self.revision_manager.get_for_object(obj)
+            queryset = reversion_api.get_for_object(obj)
             version1 = get_object_or_404(queryset, pk=version_id1)
             version2 = get_object_or_404(queryset, pk=version_id2)
 
@@ -120,7 +121,6 @@ def get_context_data(self, **kwargs):
                 )
                 context.update({'prev_url': prev_url})
 
-
         # Compile the context.
         context.update({
             "action_list": action_list,
diff --git a/setup.py b/setup.py
index 2e6ad628..994111ee 100755
--- a/setup.py
+++ b/setup.py
@@ -182,10 +182,6 @@ def rmtree(path):
 
     sys.exit(0)
 
-
-
-
-
 def get_authors():
     try:
         with open(os.path.join(PACKAGE_ROOT, "AUTHORS"), "r") as f:
@@ -217,12 +213,9 @@ def get_authors():
     ],
     zip_safe=False,
     classifiers=[
-#        "Development Status :: 4 - Beta",
         "Development Status :: 5 - Production/Stable",
         "Environment :: Web Environment",
         "Intended Audience :: Developers",
-#        "Intended Audience :: Education",
-#        "Intended Audience :: End Users/Desktop",
         "License :: OSI Approved :: GNU General Public License (GPL)",
         "Programming Language :: Python",
         "Programming Language :: Python :: 2.7",
diff --git a/tests/admin.py b/tests/admin.py
index f6da10d0..4152ab56 100644
--- a/tests/admin.py
+++ b/tests/admin.py
@@ -12,10 +12,6 @@
 
 from __future__ import unicode_literals, print_function
 
-
-from reversion.models import Revision, Version
-from reversion.revisions import RevisionManager
-
 from django.contrib import admin
 from reversion_compare.admin import CompareVersionAdmin
 
@@ -23,7 +19,6 @@
     VariantModel, CustomModel, Identity
 
 
-
 class SimpleModelAdmin(CompareVersionAdmin):
     pass
 admin.site.register(SimpleModel, SimpleModelAdmin)
@@ -33,6 +28,7 @@ class FactoryAdmin(CompareVersionAdmin):
     pass
 admin.site.register(Factory, FactoryAdmin)
 
+
 class CarAdmin(CompareVersionAdmin):
     pass
 admin.site.register(Car, CarAdmin)
@@ -42,6 +38,7 @@ class PersonAdmin(CompareVersionAdmin):
     pass
 admin.site.register(Person, PersonAdmin)
 
+
 class PetAdmin(CompareVersionAdmin):
     pass
 admin.site.register(Pet, PetAdmin)
@@ -52,16 +49,14 @@ class VariantModelAdmin(CompareVersionAdmin):
 admin.site.register(VariantModel, VariantModelAdmin)
 
 
-custom_revision_manager = RevisionManager("custom")
-
 class CustomModelAdmin(CompareVersionAdmin):
-    revision_manager = custom_revision_manager
+    pass
+
 admin.site.register(CustomModel, CustomModelAdmin)
 
 admin.site.register(Identity, CustomModelAdmin)
 
 
-
 """
 class RelatedModelInline(admin.StackedInline):
     model = RelatedModel
diff --git a/tests/models.py b/tests/models.py
index 74e32051..e06dc1c6 100644
--- a/tests/models.py
+++ b/tests/models.py
@@ -24,10 +24,11 @@
 @python_2_unicode_compatible
 class SimpleModel(models.Model):
     text = models.CharField(max_length=255)
+
     def __str__(self):
         return "SimpleModel pk: %r text: %r" % (self.pk, self.text)
 
-#------------------------------------------------------------------------------
+# ------------------------------------------------------------------------------
 
 """
 models with relationships
@@ -42,23 +43,29 @@ def __str__(self):
     https://github.com/etianen/django-reversion/wiki/Low-level-API
 """
 
+
 @python_2_unicode_compatible
 class Building(models.Model):
     address = models.CharField(max_length=128)
+
     def __str__(self):
         return self.address
 
+
 @python_2_unicode_compatible
 class Factory(Building):
     name = models.CharField(max_length=128)
+
     def __str__(self):
         return self.name
 
+
 @python_2_unicode_compatible
 class Car(models.Model):
     name = models.CharField(max_length=128)
     manufacturer = models.ForeignKey(Factory, related_name="cars")
     supplier = models.ManyToManyField(Factory, related_name="suppliers", blank=True)
+
     def __str__(self):
         return "%s from %s supplier(s): %s" % (self.name, self.manufacturer, ", ".join([s.name for s in self.supplier.all()]))
 
@@ -66,27 +73,31 @@ def __str__(self):
 @python_2_unicode_compatible
 class Pet(models.Model):
     name = models.CharField(max_length=100)
+
     def __str__(self):
         return self.name
 
+
 @python_2_unicode_compatible
 class Person(models.Model):
     name = models.CharField(max_length=100)
     pets = models.ManyToManyField(Pet, blank=True)
     # If you work someone, its at a build, but maybe not a factory!
     workplace = models.ForeignKey(Building, related_name="workers", null=True)
+
     def __str__(self):
         return self.name
 
+
 @python_2_unicode_compatible
 class Identity(models.Model):
     id_numer = models.CharField(max_length=100)
     person = models.OneToOneField(Person, related_name='_identity')
+
     def __str__(self):
         return self.id_numer
 
 reversion_api.register(Person, follow=["pets"])
-#reversion_api.register(Pet, follow=["person_set"])
 reversion_api.register(Pet)
 
 
@@ -130,6 +141,8 @@ class VariantModel(models.Model):
     email = models.EmailField(blank=True, null=True)
     url = models.URLField(blank=True, null=True)
 
+    file_field = models.FileField(blank=True, null=True)
+
     filepath = models.FilePathField(
         path=settings.UNITTEST_TEMP_PATH,
         blank=True, null=True
@@ -140,10 +153,9 @@ class VariantModel(models.Model):
     def __str__(self):
         return "VariantModel instance pk: %i" % self.pk
 
-#------------------------------------------------------------------------------
 
 class CustomModel(models.Model):
-    "Model which uses a custom version manager."
+    """Model which uses a custom version manager."""
     text = models.TextField()
 
 """
diff --git a/tests/test_custom_model.py b/tests/test_custom_model.py
index 2ee73b87..21d08aa5 100644
--- a/tests/test_custom_model.py
+++ b/tests/test_custom_model.py
@@ -17,8 +17,6 @@
 
 from __future__ import absolute_import, division, print_function
 
-from django.core.urlresolvers import reverse
-
 try:
     import django_tools
 except ImportError as err:
@@ -29,21 +27,15 @@
     ) % err
     raise ImportError(msg)
 
-
+from django.core.urlresolvers import reverse
 from reversion_compare import reversion_api
-
-
 from tests.models import CustomModel
-
-# Needs to import admin module to register all models via CompareVersionAdmin/VersionAdmin
-from tests.admin import custom_revision_manager
-
 from .test_utils.test_cases import BaseTestCase
 from .test_utils.test_data import TestData
 
 
 class CustomModelTest(BaseTestCase):
-    "Test a model which uses a custom reversion manager."
+    """Test a model which uses a custom reversion manager."""
 
     def setUp(self):
         super(CustomModelTest, self).setUp()
@@ -51,18 +43,17 @@ def setUp(self):
         self.item = test_data.create_CustomModel_data()
 
     def test_initial_state(self):
-        "Test initial data creation and model registration."
-        self.assertTrue(custom_revision_manager.is_registered(CustomModel))
+        """"Test initial data creation and model registration."""
         self.assertEqual(CustomModel.objects.count(), 1)
-        self.assertEqual(custom_revision_manager.get_for_object(self.item).count(), 1)
+        self.assertEqual(reversion_api.get_for_object(self.item).count(), 1)
         self.assertEqual(reversion_api.Revision.objects.all().count(), 1)
 
     def test_text_diff(self):
-        "Generate a new revision and check for a correctly generated diff."
+        """"Generate a new revision and check for a correctly generated diff."""
         with reversion_api.create_revision():
             self.item.text = "version two"
             self.item.save()
-        queryset = custom_revision_manager.get_for_object(self.item)
+        queryset = reversion_api.get_for_object(self.item)
         version_ids = queryset.values_list("pk", flat=True)
         self.assertEqual(len(version_ids), 2)
         url_name = 'admin:%s_%s_compare' % (CustomModel._meta.app_label, CustomModel._meta.model_name)
@@ -73,20 +64,21 @@ def test_text_diff(self):
         self.assertContains(response, "+ version two ")
 
     def test_version_selection(self):
-        "Generate two revisions and view the version history selection."
+        """Generate two revisions and view the version history selection."""
         with reversion_api.create_revision():
             self.item.text = "version two"
             self.item.save()
         with reversion_api.create_revision():
             self.item.text = "version three"
             self.item.save()
-        queryset = custom_revision_manager.get_for_object(self.item)
+        queryset = reversion_api.get_for_object(self.item)
         version_ids = queryset.values_list("pk", flat=True)
         self.assertEqual(len(version_ids), 3)
         url_name = 'admin:%s_%s_history' % (CustomModel._meta.app_label, CustomModel._meta.model_name)
         history_url = reverse(url_name, args=(self.item.pk, ))
         response = self.client.get(history_url)
-        self.assertContainsHtml(response,
+        self.assertContainsHtml(
+            response,
             'manufacturer*  ',
             'supplier*  ',
             '''
@@ -97,18 +92,18 @@ def test_diff1(self):
                 always the same supplier*      
             ''',
-            'Note: ', # info for non-follow related informations
-            'version 2: change ForeignKey and ManyToManyField. ', # edit comment
+            'Note: ',  # info for non-follow related informations
+            'version 2: change ForeignKey and ManyToManyField. ',
         )
 
     def test_diff2(self):
         response = self.client.get(
             "/admin/tests/car/%s/history/compare/" % self.car.pk,
-            data={"version_id2":self.version_ids[0], "version_id1":self.version_ids[1]}
+            data={"version_id2": self.version_ids[0], "version_id1":self.version_ids[1]}
         )
-#        debug_response(response) # from django-tools
-
-        self.assertContainsHtml(response,
+        # debug_response(response) # from django-tools
+        self.assertContainsHtml(
+            response,
             "- motor-car one",
             "+ motor-car II ",
 
@@ -120,12 +115,11 @@ def test_diff2(self):
                 always the same supplier* Note: ', # info for non-follow related informations
-            'version 3: change CharField, ForeignKey and ManyToManyField. ', # edit comment
+            'Note: ',  # info for non-follow related informations
+            'version 3: change CharField, ForeignKey and ManyToManyField. ',
         )
 
 
-
 class FactoryCarModelTest2(BaseTestCase):
     """
     unittests that used:
@@ -161,7 +155,7 @@ def test_deleted_objects(self):
 
         with reversion_api.create_revision():
             factory2 = Factory.objects.create(name="factory two", address="1 Fake Plaza")
-            car.manufacturer=factory2
+            car.manufacturer = factory2
             car.save()
 
         with reversion_api.create_revision():
@@ -173,9 +167,8 @@ def test_deleted_objects(self):
 
         # response = self.client.get("/admin/tests/car/%s/history/" % car.pk)
         # debug_response(response) # from django-tools
-
-        response = self.client.get(
+        self.client.get(
             "/admin/tests/car/%s/history/compare/" % car.pk,
-            data={"version_id2":version_ids[0], "version_id1":version_ids[1]}
+            data={"version_id2": version_ids[0], "version_id1": version_ids[1]}
         )
         # debug_response(response) # from django-tools
diff --git a/tests/test_factory_car_reverse_models.py b/tests/test_factory_car_reverse_models.py
index b034d079..310978bf 100644
--- a/tests/test_factory_car_reverse_models.py
+++ b/tests/test_factory_car_reverse_models.py
@@ -27,14 +27,13 @@
         " - Original error: %s"
     ) % err
     raise ImportError(msg)
-from django_tools.unittest_utils.BrowserDebug import debug_response
 
 from reversion_compare import reversion_api
-
 from .models import Factory, Car, Person
 from .test_utils.test_cases import BaseTestCase
 from .test_utils.test_data import TestData
 
+
 class FactoryCarReverseRelationModelTest(BaseTestCase):
     """
     unittests that used:
@@ -48,7 +47,7 @@ def setUp(self):
         reversion_api.unregister(Person)
         reversion_api.unregister(Car)
         reversion_api.unregister(Factory)
-        reversion_api.register(Factory, follow=["building_ptr","cars","workers"])
+        reversion_api.register(Factory, follow=["building_ptr", "cars", "workers"])
         reversion_api.register(Car)
         reversion_api.register(Person, follow=["pets"])
         super(FactoryCarReverseRelationModelTest, self).setUp()
@@ -61,15 +60,16 @@ def setUp(self):
     def test_initial_state(self):
         self.assertTrue(reversion_api.is_registered(Factory))
         self.assertTrue(reversion_api.is_registered(Car))
+        self.assertTrue(reversion_api.is_registered(Person))
         self.assertEqual(reversion_api.Revision.objects.all().count(), 3)
         self.assertEqual(len(self.version_ids), 3)
         self.assertEqual(reversion_api.Version.objects.all().count(), 19)
 
     def test_select_compare(self):
         response = self.client.get("/admin/tests/factory/%s/history/" % self.factory.pk)
-#        debug_response(response) # from django-tools
-
-        self.assertContainsHtml(response,
+        # debug_response(response) # from django-tools
+        self.assertContainsHtml(
+            response,
             '
                 - motor-car three from factory one supplier(s): → Deleted+ Bob Bobertson 
             ''',
-            'version 2: discontinued car-three, add car-four, add Bob the worker ', # edit comment
+            'version 2: discontinued car-three, add car-four, add Bob the worker ',  # edit comment
         )
-
diff --git a/tests/test_onetoone_field.py b/tests/test_onetoone_field.py
index 01ed783a..a105793c 100644
--- a/tests/test_onetoone_field.py
+++ b/tests/test_onetoone_field.py
@@ -16,7 +16,6 @@
 
 from __future__ import absolute_import, division, print_function
 
-
 try:
     import django_tools
 except ImportError as err:
@@ -27,11 +26,7 @@
     ) % err
     raise ImportError(msg)
 
-try:
-    from reversion.revisions import get_for_object
-except ImportError:
-    from reversion import get_for_object
-
+from reversion_compare import reversion_api
 from .test_utils.test_cases import BaseTestCase
 from .test_utils.test_data import TestData
 
@@ -44,13 +39,14 @@ def setUp(self):
         test_data = TestData(verbose=False)
         self.person, self.item = test_data.create_PersonIdentity_data()
 
-        queryset = get_for_object(self.person)
+        queryset = reversion_api.get_for_object(self.person)
         self.version_ids = queryset.values_list("pk", flat=True)
 
     def test_select_compare(self):
         response = self.client.get("/admin/tests/person/%s/history/" % self.person.pk)
 
-        self.assertContainsHtml(response,
+        self.assertContainsHtml(
+            response,
             '
                 - Dave
diff --git a/tests/test_person_pet_models.py b/tests/test_person_pet_models.py
index 6bf7dabc..71e7b2dd 100644
--- a/tests/test_person_pet_models.py
+++ b/tests/test_person_pet_models.py
@@ -17,7 +17,6 @@
 
 from __future__ import absolute_import, division, print_function
 
-
 try:
     import django_tools
 except ImportError as err:
@@ -28,17 +27,14 @@
     ) % err
     raise ImportError(msg)
 
-
 from reversion_compare import reversion_api
-
-
 from tests.models import Person, Pet
 
 # Needs to import admin module to register all models via CompareVersionAdmin/VersionAdmin
-
 from .test_utils.test_cases import BaseTestCase
 from .test_utils.test_data import TestData
 
+
 class PersonPetModelTest(BaseTestCase):
     """
     unittests that used:
@@ -55,7 +51,7 @@ def setUp(self):
         super(PersonPetModelTest, self).setUp()
 
         test_data = TestData(verbose=False)
-#        test_data = TestData(verbose=True)
+        # test_data = TestData(verbose=True)
         self.pet1, self.pet2, self.person = test_data.create_PersonPet_data()
 
         queryset = reversion_api.get_for_object(self.person)
@@ -72,8 +68,9 @@ def test_initial_state(self):
 
     def test_select_compare(self):
         response = self.client.get("/admin/tests/person/%s/history/" % self.person.pk)
-#        debug_response(response) # from django-tools
-        self.assertContainsHtml(response,
+        # debug_response(response) # from django-tools
+        self.assertContainsHtml(
+            response,
             '
                 would be changed pet → Is changed pet 
             """,
-            "version 2: change follow related pets. ", # edit comment
+            "version 2: change follow related pets. ",  # edit comment
         )
-        self.assertNotContainsHtml(response,
-            "name ", # person name doesn't changed
-            'class="follow"'# All fields are under reversion control
+        self.assertNotContainsHtml(
+            response,
+            "name ",  # person name doesn't changed
+            'class="follow"'  # All fields are under reversion control
         )
 
     def test_add_m2m(self):
@@ -119,8 +117,9 @@ def test_add_m2m(self):
         self.assertEqual(len(version_ids), 3)
 
         response = self.client.get("/admin/tests/person/%s/history/" % self.person.pk)
-#        debug_response(response) # from django-tools
-        self.assertContainsHtml(response,
+        # debug_response(response) # from django-tools
+        self.assertContainsHtml(
+            response,
             '
                 + added pet 
             """,
-            "version 3: add a pet ", # edit comment
+            "version 3: add a pet ",  # edit comment
         )
-        self.assertNotContainsHtml(response,
-            "name ", # person name doesn't changed
-            'class="follow"'# All fields are under reversion control
+        self.assertNotContainsHtml(
+            response,
+            "name ",  # person name doesn't changed
+            'class="follow"'  # All fields are under reversion control
         )
 
     def test_m2m_not_changed(self):
@@ -165,8 +166,9 @@ def test_m2m_not_changed(self):
         self.assertEqual(len(version_ids), 3)
 
         response = self.client.get("/admin/tests/person/%s/history/" % self.person.pk)
-#        debug_response(response) # from django-tools
-        self.assertContainsHtml(response,
+        # debug_response(response) # from django-tools
+        self.assertContainsHtml(
+            response,
             '
             - Dave
             + David 
              
             ''',
-            "version 3: change the name ", # edit comment
+            "version 3: change the name ",  # edit comment
         )
-        self.assertNotContainsHtml(response,
+        self.assertNotContainsHtml(
+            response,
             "pet",
-            'class="follow"'# All fields are under reversion control
+            'class="follow"'  # All fields are under reversion control
         )
-
-
diff --git a/tests/test_settings.py b/tests/test_settings.py
index 1e378a28..bc00297f 100644
--- a/tests/test_settings.py
+++ b/tests/test_settings.py
@@ -15,8 +15,6 @@
     'django.contrib.messages.middleware.MessageMiddleware',
 
     "reversion.middleware.RevisionMiddleware",
-    
-    #'django_tools.middlewares.QueryLogMiddleware.QueryLogMiddleware',
 )
 
 LANGUAGE_CODE = "en"
@@ -58,7 +56,7 @@
     }
 }
 
-DEBUG=True
+DEBUG = True
 
 # add reversion models to django admin:
-ADD_REVERSION_ADMIN=True
\ No newline at end of file
+ADD_REVERSION_ADMIN = True
\ No newline at end of file
diff --git a/tests/test_simple_model.py b/tests/test_simple_model.py
index c542a122..9e446a61 100644
--- a/tests/test_simple_model.py
+++ b/tests/test_simple_model.py
@@ -26,12 +26,8 @@
         " - Original error: %s"
     ) % err
     raise ImportError(msg)
-from django_tools.unittest_utils.BrowserDebug import debug_response
-
 
 from reversion_compare import reversion_api, helpers
-
-
 from .test_utils.test_cases import BaseTestCase
 from .models import SimpleModel
 from .test_utils.test_data import TestData
@@ -46,7 +42,7 @@ class SimpleModelTest(BaseTestCase):
     def setUp(self):
         super(SimpleModelTest, self).setUp()
         test_data = TestData(verbose=False)
-#        test_data = TestData(verbose=True)
+        # test_data = TestData(verbose=True)
         self.item1, self.item2 = test_data.create_Simple_data()
 
         queryset = reversion_api.get_for_object(self.item1)
@@ -72,8 +68,9 @@ def test_initial_state(self):
 
     def test_select_compare1(self):
         response = self.client.get("/admin/tests/simplemodel/%s/history/" % self.item1.pk)
-#        debug_response(response) # from django-tools
-        self.assertContainsHtml(response,
+        #  debug_response(response) # from django-tools
+        self.assertContainsHtml(
+            response,
             '%s " % comment,
                 '- version one',
             '+ version two ',
-            'simply change the CharField text. ', # edit comment
+            'simply change the CharField text. ',  # edit comment
         )
 
         if self.google_diff_match_patch:
             # google-diff-match-patch is available
             helpers.google_diff_match_patch = True
             try:
-                self.assertContainsHtml(response,
+                self.assertContainsHtml(
+                    response,
                     """
                     version  
                     one
                     two 
                     
                     """,
-                    'simply change the CharField text. ', # edit comment
+                    'simply change the CharField text. ',  # edit comment
                 )
             finally:
                 helpers.google_diff_match_patch = False # revert
 
     def test_prev_next_buttons(self):
-        base_url="/admin/tests/simplemodel/%s/history/compare/" % self.item2.pk
+        base_url = "/admin/tests/simplemodel/%s/history/compare/" % self.item2.pk
         for i in range(4):
             # IDs: 3,4,5,6
-            id1=i+3
-            id2=i+4
-            response = self.client.get(base_url,
-                data={"version_id2":id2, "version_id1":id1}
+            id1 = i+3
+            id2 = i+4
+            response = self.client.get(
+                base_url,
+                data={"version_id2": id2, "version_id1": id1}
             )
-            self.assertContainsHtml(response,
+            self.assertContainsHtml(
+                response,
                 '- v%i' % i,
                 '+ v%i ' % (i+1),
                 'change to v%i ' % (i+1),
@@ -142,7 +143,6 @@ def test_prev_next_buttons(self):
             # for line in response.content.decode("utf-8").split("\n"):
             #     if "next" in line or "previous" in line:
             #         print(line)
-
             """
             +++ 0
                  next › next › ' % (i+4, i+5)
-            prev = '‹ previous ' % (i+2,i+3)
+            prev = '‹ previous ' % (i+2, i+3)
 
-            if i==0:
+            if i == 0:
                 self.assertNotContains(response, "previous")
                 self.assertContains(response, "next")
                 self.assertContainsHtml(response, next)
-            elif i==3:
+            elif i == 3:
                 self.assertContains(response, "previous")
                 self.assertNotContains(response, "next")
                 self.assertContainsHtml(response, prev)
             else:
                 self.assertContains(response, "previous")
                 self.assertContains(response, "next")
-                self.assertContainsHtml(response, prev, next)
\ No newline at end of file
+                self.assertContainsHtml(response, prev, next)
diff --git a/tests/test_utils/test_cases.py b/tests/test_utils/test_cases.py
index c946d897..5c5b7dae 100644
--- a/tests/test_utils/test_cases.py
+++ b/tests/test_utils/test_cases.py
@@ -29,14 +29,11 @@
         " - Original error: %s"
     ) % err
     raise ImportError(msg)
-from django_tools.unittest_utils.BrowserDebug import debug_response
-
 
+from django_tools.unittest_utils.BrowserDebug import debug_response
 from reversion_compare import reversion_api, helpers
 
-
 # Needs to import admin module to register all models via CompareVersionAdmin/VersionAdmin
-from tests.admin import custom_revision_manager
 from .test_data import TestData
 
 
@@ -73,7 +70,7 @@ def assertContainsHtml(self, response, *args):
             try:
                 self.assertContains(response, html, html=True)
             except AssertionError as e:
-                debug_response(response, msg="%s" % e) # from django-tools
+                debug_response(response, msg="%s" % e)  # from django-tools
                 raise
 
     def assertNotContainsHtml(self, response, *args):
@@ -81,7 +78,7 @@ def assertNotContainsHtml(self, response, *args):
             try:
                 self.assertNotContains(response, html, html=True)
             except AssertionError as e:
-                debug_response(response, msg="%s" % e) # from django-tools
+                debug_response(response, msg="%s" % e)  # from django-tools
                 raise
 
 
@@ -96,6 +93,5 @@ def test_model_registering(self):
         models = test_app_config.get_models(
             include_auto_created=False, include_deferred=False, include_swapped=False
         )
-        default_registered = len(reversion_api.get_registered_models())
-        custom_registered = len(custom_revision_manager.get_registered_models())
-        self.assertEqual(default_registered + custom_registered, len(tuple(models)))
+        default_registered = len(list(reversion_api.get_registered_models()))
+        self.assertEqual(default_registered, len(tuple(models)))
diff --git a/tests/test_utils/test_data.py b/tests/test_utils/test_data.py
index 9e892c1f..a055f369 100644
--- a/tests/test_utils/test_data.py
+++ b/tests/test_utils/test_data.py
@@ -35,13 +35,8 @@
     ) % err
     raise ImportError(msg)
 
-
 from reversion_compare import reversion_api
-
-
-from tests.models import SimpleModel, Person, Pet, \
-    Factory, Car, VariantModel, CustomModel, Identity
-
+from tests.models import SimpleModel, Person, Pet, Factory, Car, VariantModel, CustomModel, Identity
 
 
 class TestData(object):
@@ -50,8 +45,8 @@ class TestData(object):
     This will be also used from external scripts, too!
     """
 
-    TEST_USERNAME="test"
-    TEST_USERPASS="12345678"
+    TEST_USERNAME = "test"
+    TEST_USERPASS = "12345678"
 
     def __init__(self, verbose=False):
         self.verbose = verbose
@@ -68,7 +63,6 @@ def create_all(self):
                 func = getattr(self, method_name)
                 func()
 
-
     def create_testuser_data(self):
         if self.verbose:
             print("\t+++ user name.......: %r" % self.TEST_USERNAME)
@@ -94,7 +88,7 @@ def create_Simple_data(self):
 
         for no in range(5):
             with reversion_api.create_revision():
-                if no==0:
+                if no == 0:
                     item2 = SimpleModel.objects.create(text="v0")
                     reversion_api.set_comment("create v%i" % no)
                 else:
@@ -227,6 +221,7 @@ def create_Factory_reverse_relation_data(self):
                 name="Bob Bobertson",
                 workplace=manufacturer
             )
+            worker1.save()
 
             manufacturer.save()
             reversion_api.set_comment("version 2: discontinued car-three, add car-four, add Bob the worker")
@@ -329,6 +324,8 @@ def create_VariantModel_data(self):
                 email = "one@foo-bar.com",
                 url = "http://www.pylucid.org/",
 
+                file_field = os.path.join(settings.UNITTEST_TEMP_PATH, "foo"),
+
                 filepath = os.path.join(settings.UNITTEST_TEMP_PATH, "foo"),
 
                 ip_address = "192.168.0.1",
@@ -357,6 +354,7 @@ def create_VariantModel_data(self):
             ("float", 3.1415),
             ("email", "two@foo-bar.com"),
             ("url", "https://github.com/jedie/"),
+            ("file_field", os.path.join(settings.UNITTEST_TEMP_PATH, "bar")),
             ("filepath", os.path.join(settings.UNITTEST_TEMP_PATH, "bar")),
             ("ip_address", "10.0.0.0"),
         )
@@ -377,7 +375,6 @@ def create_CustomModel_data(self):
 
         return item1
 
-
     def create_PersonIdentity_data(self):
         with reversion_api.create_revision():
             person = Person.objects.create(name="Dave")
diff --git a/tests/test_variant_model.py b/tests/test_variant_model.py
index 31e31c36..61572c9d 100644
--- a/tests/test_variant_model.py
+++ b/tests/test_variant_model.py
@@ -20,7 +20,6 @@
 import os
 from django.conf import settings
 
-
 try:
     import django_tools
 except ImportError as err:
@@ -30,14 +29,10 @@
               " - Original error: %s"
           ) % err
     raise ImportError(msg)
-from django_tools.unittest_utils.BrowserDebug import debug_response
-
 from reversion_compare import reversion_api
-
 from tests.models import VariantModel
 
 # Needs to import admin module to register all models via CompareVersionAdmin/VersionAdmin
-
 from .test_utils.test_cases import BaseTestCase
 from .test_utils.test_data import TestData
 
@@ -71,12 +66,10 @@ def test_textfield(self):
 last line"""
             item.save()
 
-        # debug_response(self.client.get("/admin/tests/variantmodel/1/history/"))
         response = self.client.get(
             "/admin/tests/variantmodel/1/history/compare/",
             data={"version_id2": 1, "version_id1": 2}
         )
-        # debug_response(response) # from django-tools
 
         self.assertContains(response, """\
 -nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit
@@ -111,7 +104,6 @@ def test_initial_state(self):
 
     def test_all_changes(self):
         # debug_response(self.client.get("/admin/tests/variantmodel/1/history/"))
-
         # compare initial with last version
         response = self.client.get(
             "/admin/tests/variantmodel/1/history/compare/",
@@ -120,14 +112,14 @@ def test_all_changes(self):
                 "version_id1": len(self.test_data) + 1  # incl. initial
             }
         )
-        # debug_response(response) # from django-tools
 
         field_headlines = [
             "%s " % field_name.replace("_", " ")
             for field_name, value in self.test_data
         ]
         self.assertContainsHtml(response, *field_headlines)
-        self.assertContainsHtml(response,
+        self.assertContainsHtml(
+            response,
             "boolean ",
             'False changed to: True 
',
 
@@ -191,8 +183,8 @@ def test_all_changes(self):
             "+ https://github.com/jedie/ ",
 
             "filepath ",
-            #"- %s/foo" % settings.UNITTEST_TEMP_PATH,
-            #"+ %s/bar " % settings.UNITTEST_TEMP_PATH,
+            # "- %s/foo" % settings.UNITTEST_TEMP_PATH,
+            # "+ %s/bar " % settings.UNITTEST_TEMP_PATH,
             "- %s" % os.path.join(settings.UNITTEST_TEMP_PATH, 'foo'),
             "+ %s " % os.path.join(settings.UNITTEST_TEMP_PATH, 'bar'),
 
diff --git a/tests/test_view.py b/tests/test_view.py
index 50885f99..ad3549d7 100644
--- a/tests/test_view.py
+++ b/tests/test_view.py
@@ -23,12 +23,9 @@
         " - Original error: %s"
     ) % err
     raise ImportError(msg)
-from django_tools.unittest_utils.BrowserDebug import debug_response
 
 
 from reversion_compare import reversion_api
-
-
 from .test_utils.test_cases import BaseTestCase
 from .models import SimpleModel
 from .test_utils.test_data import TestData
@@ -65,7 +62,8 @@ def test_initial_state(self):
         
     def test_select_compare1(self):
         response = self.client.get("/test_view/%s" % self.item1.pk)
-        self.assertContainsHtml(response,
+        self.assertContainsHtml(
+            response,
             '%s " % comment,
                 '- version one',
             '+ version two ',
-            'simply change the CharField text. ', # edit comment
+            'simply change the CharField text. ',  # edit comment
         )
         
     def test_prev_next_buttons(self):
-        base_url="/test_view/%s" % self.item2.pk
+        base_url = "/test_view/%s" % self.item2.pk
         for i in range(4):
             # IDs: 3,4,5,6
-            id1=i+3
-            id2=i+4
-            response = self.client.get(base_url,
-                data={"version_id2":id2, "version_id1":id1}
+            id1 = i+3
+            id2 = i+4
+            response = self.client.get(
+                base_url,
+                data={"version_id2": id2, "version_id1": id1}
             )
-            self.assertContainsHtml(response,
+            self.assertContainsHtml(
+                response,
                 '- v%i' % i,
                 '+ v%i ' % (i+1),
                 'change to v%i ' % (i+1),
             )
 
             next = 'next › ' % (i+4, i+5)
-            prev = '‹ previous ' % (i+2,i+3)
+            prev = '‹ previous ' % (i+2, i+3)
 
-            if i==0:
+            if i == 0:
                 self.assertNotContains(response, "previous")
                 self.assertContains(response, "next")
                 self.assertContainsHtml(response, next)
-            elif i==3:
+            elif i == 3:
                 self.assertContains(response, "previous")
                 self.assertNotContains(response, "next")
                 self.assertContainsHtml(response, prev)
diff --git a/tests/views.py b/tests/views.py
index ac94a229..b9c856f2 100644
--- a/tests/views.py
+++ b/tests/views.py
@@ -2,6 +2,6 @@
 from reversion_compare.views import HistoryCompareDetailView
 from .models import SimpleModel
 
+
 class SimpleModelHistoryCompareView(HistoryCompareDetailView):
     model = SimpleModel
-    
\ No newline at end of file