From 62dc99ca997ebf0cbf19268290bf8ae8c66e3c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Wickstr=C3=B6m?= Date: Thu, 18 Jun 2015 15:11:11 +0300 Subject: [PATCH 1/4] Add OneToOne field test by adding/testing a Identity model The identity model includes an id_number which is set to char field and a OneToOne field to a user. Note that the field also sets a custom related name. This is to test that we can handle custom related names in one to one fields. --- tests/admin.py | 3 +- tests/models.py | 7 ++++ tests/test_onetoone_field.py | 72 +++++++++++++++++++++++++++++++++++ tests/test_utils/test_data.py | 18 ++++++++- 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 tests/test_onetoone_field.py diff --git a/tests/admin.py b/tests/admin.py index c6375e57..f6da10d0 100644 --- a/tests/admin.py +++ b/tests/admin.py @@ -20,7 +20,7 @@ from reversion_compare.admin import CompareVersionAdmin from .models import SimpleModel, Factory, Car, Person, Pet,\ - VariantModel, CustomModel + VariantModel, CustomModel, Identity @@ -58,6 +58,7 @@ class CustomModelAdmin(CompareVersionAdmin): revision_manager = custom_revision_manager admin.site.register(CustomModel, CustomModelAdmin) +admin.site.register(Identity, CustomModelAdmin) diff --git a/tests/models.py b/tests/models.py index 6cadfc7c..c7086684 100644 --- a/tests/models.py +++ b/tests/models.py @@ -77,6 +77,13 @@ class Person(models.Model): 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.register(Person, follow=["pets"]) #reversion.register(Pet, follow=["person_set"]) reversion.register(Pet) diff --git a/tests/test_onetoone_field.py b/tests/test_onetoone_field.py new file mode 100644 index 00000000..6ba82819 --- /dev/null +++ b/tests/test_onetoone_field.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# coding: utf-8 + +""" + django-reversion-compare unittests + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + I used the setup from reversion_compare_test_project ! + + TODO: + * models.IntegerField() + + :copyleft: 2012-2015 by the django-reversion-compare team, see AUTHORS for more details. + :license: GNU GPL v3 or above, see LICENSE for more details. +""" + +from __future__ import absolute_import, division, print_function + + +try: + import django_tools +except ImportError as err: + msg = ( + "Please install django-tools for unittests" + " - https://github.com/jedie/django-tools/" + " - Original error: %s" + ) % err + raise ImportError(msg) + +from reversion import get_for_object + +from .test_utils.test_cases import BaseTestCase +from .test_utils.test_data import TestData + + +class OneToOneFieldTest(BaseTestCase): + "Test a model which uses a custom reversion manager." + + def setUp(self): + super(OneToOneFieldTest, self).setUp() + test_data = TestData(verbose=False) + self.person, self.item = test_data.create_PersonIdentity_data() + + queryset = 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.version_ids[0], + '' % self.version_ids[0], + '' % self.version_ids[1], + '' % self.version_ids[1], + ) + + def test_compare(self): + response = self.client.get( + "/admin/tests/person/%s/history/compare/" % self.person.pk, + data={"version_id2":self.version_ids[0], "version_id1":self.version_ids[1]} + ) + + self.assertContainsHtml(response, + """ +
+                - Dave
+                + John
+            
+ """, + "
version 2: change person name.
", + ) diff --git a/tests/test_utils/test_data.py b/tests/test_utils/test_data.py index fb0123b4..b103823b 100644 --- a/tests/test_utils/test_data.py +++ b/tests/test_utils/test_data.py @@ -38,7 +38,7 @@ import reversion from tests.models import SimpleModel, Person, Pet, \ - Factory, Car, VariantModel, CustomModel + Factory, Car, VariantModel, CustomModel, Identity @@ -368,3 +368,19 @@ def create_CustomModel_data(self): return item1 + + def create_PersonIdentity_data(self): + with reversion.create_revision(): + person = Person.objects.create(name="Dave") + identity = Identity.objects.create(id_numer="1234", person=person) + + if self.verbose: + print("version 1:", person, identity) + + with reversion.create_revision(): + person.name = "John" + person.save() + reversion.set_comment("version 2: change person name.") + + return person, identity + From 40441f834db60ce5c90e1aca77f642aea3d605ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Wickstr=C3=B6m?= Date: Thu, 18 Jun 2015 13:20:59 +0300 Subject: [PATCH 2/4] Fetch OneToOne field foreign_key from the objects attribute instead of all() A OneToOne field does not have a all() function, which leads to an exception when all() is called. --- reversion_compare/admin.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/reversion_compare/admin.py b/reversion_compare/admin.py index 51142691..5a2cf28d 100644 --- a/reversion_compare/admin.py +++ b/reversion_compare/admin.py @@ -25,6 +25,7 @@ except ImportError: # Django < 1.7 from django.contrib.admin.util import unquote, quote from django.core.urlresolvers import reverse +from django.core.exceptions import ObjectDoesNotExist from django.db import models from django.http import Http404 from django.contrib import admin @@ -108,7 +109,14 @@ def get_reverse_foreign_key(self): obj = self.version.object_version.object # self = getattr(obj, self.field.related_name) #self.field.field_name if self.has_int_pk and self.field.related_name and hasattr(obj, self.field.related_name): - ids = [v.id for v in getattr(obj, str(self.field.related_name)).all()] # is: version.field_dict[field.name] + if isinstance(self.field, models.fields.related.OneToOneRel): + try: + ids = [getattr(obj, str(self.field.related_name)).pk] + except ObjectDoesNotExist: + ids = [] + else: + ids = [v.id for v in getattr(obj, str(self.field.related_name)).all()] # is: version.field_dict[field.name] + else: return ([], [], [], []) # TODO: refactory that From e6236803b4daf8a913e13ee128bc39258c177b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Wickstr=C3=B6m?= Date: Thu, 18 Jun 2015 13:21:11 +0300 Subject: [PATCH 3/4] Remove commented line --- reversion_compare/admin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/reversion_compare/admin.py b/reversion_compare/admin.py index 5a2cf28d..85f014c9 100644 --- a/reversion_compare/admin.py +++ b/reversion_compare/admin.py @@ -107,7 +107,6 @@ def get_related(self): def get_reverse_foreign_key(self): obj = self.version.object_version.object - # self = getattr(obj, self.field.related_name) #self.field.field_name if self.has_int_pk and self.field.related_name and hasattr(obj, self.field.related_name): if isinstance(self.field, models.fields.related.OneToOneRel): try: From 7b093e396c63374e90b0b301e39bd2f83dd94baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Wickstr=C3=B6m?= Date: Wed, 22 Jul 2015 12:00:54 +0300 Subject: [PATCH 4/4] Add Frank to AUTHORS --- AUTHORS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 9bceb09b..93a2fd5c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -19,4 +19,5 @@ CONTRIBUTORS are and/or have been (alphabetic order): Github: * C. Barrionuevo da Luz, Fabio Github: - +* Wickström, Frank + Github: