From e6c7b567d1b03df8123eb6f8ae2706b37a602513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Wed, 21 Aug 2019 11:02:23 +0200 Subject: [PATCH] Remove unsupported django version hacks. --- model_utils/fields.py | 13 +++---- model_utils/managers.py | 34 ------------------- model_utils/models.py | 14 ++------ model_utils/tracker.py | 2 -- tests/fields.py | 25 +++++--------- tests/test_fields/test_field_tracker.py | 22 +++--------- .../test_managers/test_inheritance_manager.py | 8 +---- tests/test_models/test_deferred_fields.py | 25 +++++--------- translations.py | 4 --- 9 files changed, 29 insertions(+), 118 deletions(-) diff --git a/model_utils/fields.py b/model_utils/fields.py index 49a3185..693242d 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -81,9 +81,7 @@ class StatusField(models.CharField): assert hasattr(sender, self.choices_name), \ "To use StatusField, the model '%s' must have a %s choices class attribute." \ % (sender.__name__, self.choices_name) - self._choices = getattr(sender, self.choices_name) - if django.VERSION >= (1, 9, 0): - self.choices = self._choices + self.choices = getattr(sender, self.choices_name) if not self.has_default(): self.default = tuple(getattr(sender, self.choices_name))[0][0] # set first as default @@ -92,9 +90,7 @@ class StatusField(models.CharField): # we don't set the real choices until class_prepared (so we can rely on # the STATUS class attr being available), but we need to set some dummy # choices now so the super method will add the get_FOO_display method - self._choices = [(0, 'dummy')] - if django.VERSION >= (1, 9, 0): - self.choices = self._choices + self.choices = [(0, 'dummy')] super(StatusField, self).contribute_to_class(cls, name) def deconstruct(self): @@ -133,11 +129,10 @@ class MonitorField(models.DateTimeField): return getattr(instance, self.monitor) def _save_initial(self, sender, instance, **kwargs): - if django.VERSION >= (1, 10) and self.monitor in instance.get_deferred_fields(): + if self.monitor in instance.get_deferred_fields(): # Fix related to issue #241 to avoid recursive error on double monitor fields return - setattr(instance, self.monitor_attname, - self.get_monitored_value(instance)) + setattr(instance, self.monitor_attname, self.get_monitored_value(instance)) def pre_save(self, model_instance, add): value = now() diff --git a/model_utils/managers.py b/model_utils/managers.py index 0b4a887..9f34bdd 100644 --- a/model_utils/managers.py +++ b/model_utils/managers.py @@ -114,35 +114,6 @@ class InheritanceQuerySetMixin(object): qset._annotated = [a.default_alias for a in args] + list(kwargs.keys()) return qset - def iterator(self): - # Maintained for Django 1.8 compatability - iter = super(InheritanceQuerySetMixin, self).iterator() - if getattr(self, 'subclasses', False): - extras = tuple(self.query.extra.keys()) - # sort the subclass names longest first, - # so with 'a' and 'a__b' it goes as deep as possible - subclasses = sorted(self.subclasses, key=len, reverse=True) - for obj in iter: - sub_obj = None - for s in subclasses: - sub_obj = self._get_sub_obj_recurse(obj, s) - if sub_obj: - break - if not sub_obj: - sub_obj = obj - - if getattr(self, '_annotated', False): - for k in self._annotated: - setattr(sub_obj, k, getattr(obj, k)) - - for k in extras: - setattr(sub_obj, k, getattr(obj, k)) - - yield sub_obj - else: - for obj in iter: - yield obj - def _get_subclasses_recurse(self, model, levels=None): """ Given a Model class, find all related objects, exploring children @@ -202,11 +173,6 @@ class InheritanceQuerySetMixin(object): def _get_sub_obj_recurse(self, obj, s): rel, _, s = s.partition(LOOKUP_SEP) - # Django 1.9: If a primitive type gets passed to this recursive function, - # return None as non-models are not part of inheritance. - if not isinstance(obj, models.Model): - return None - try: node = getattr(obj, rel) except ObjectDoesNotExist: diff --git a/model_utils/models.py b/model_utils/models.py index 6083015..c93fe2d 100644 --- a/model_utils/models.py +++ b/model_utils/models.py @@ -18,11 +18,7 @@ from model_utils.managers import ( SoftDeletableManager, ) -if django.VERSION >= (1, 9, 0): - from django.db.models.functions import Now - now = Now() -else: - from django.utils.timezone import now +from django.utils.timezone import now class TimeStampedModel(models.Model): @@ -75,9 +71,7 @@ def add_status_query_managers(sender, **kwargs): if not issubclass(sender, StatusModel): return - if django.VERSION >= (1, 10): - # First, get current manager name... - default_manager = sender._meta.default_manager + default_manager = sender._meta.default_manager for value, display in getattr(sender, 'STATUS', ()): if _field_exists(sender, value): @@ -88,9 +82,7 @@ def add_status_query_managers(sender, **kwargs): ) sender.add_to_class(value, QueryManager(status=value)) - if django.VERSION >= (1, 10): - # ...then, put it back, as add_to_class is modifying the default manager! - sender._meta.default_manager_name = default_manager.name + sender._meta.default_manager_name = default_manager.name def add_timeframed_query_manager(sender, **kwargs): diff --git a/model_utils/tracker.py b/model_utils/tracker.py index 5c7c7d8..fa93a74 100644 --- a/model_utils/tracker.py +++ b/model_utils/tracker.py @@ -93,8 +93,6 @@ class FieldInstanceTracker(object): self.instance = instance self.fields = fields self.field_map = field_map - if django.VERSION < (1, 10): - self.init_deferred_fields() @property def deferred_fields(self): diff --git a/tests/fields.py b/tests/fields.py index 7c29aa4..230f128 100644 --- a/tests/fields.py +++ b/tests/fields.py @@ -22,22 +22,13 @@ def mutable_to_db(value): return str(value) -if django.VERSION >= (1, 9, 0): - class MutableField(models.TextField): - def to_python(self, value): - return mutable_from_db(value) +class MutableField(models.TextField): + def to_python(self, value): + return mutable_from_db(value) - def from_db_value(self, value, expression, connection, context): - return mutable_from_db(value) + def from_db_value(self, value, expression, connection, context): + return mutable_from_db(value) - def get_db_prep_save(self, value, connection): - value = super(MutableField, self).get_db_prep_save(value, connection) - return mutable_to_db(value) -else: - class MutableField(with_metaclass(models.SubfieldBase, models.TextField)): - def to_python(self, value): - return mutable_from_db(value) - - def get_db_prep_save(self, value, connection): - value = mutable_to_db(value) - return super(MutableField, self).get_db_prep_save(value, connection) + def get_db_prep_save(self, value, connection): + value = super(MutableField, self).get_db_prep_save(value, connection) + return mutable_to_db(value) diff --git a/tests/test_fields/test_field_tracker.py b/tests/test_fields/test_field_tracker.py index 2efe9cf..40cf1ab 100644 --- a/tests/test_fields/test_field_tracker.py +++ b/tests/test_fields/test_field_tracker.py @@ -185,35 +185,23 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests): self.instance.number = 1 self.instance.save() item = self.tracked_class.objects.only('name').first() - if django.VERSION >= (1, 10): - self.assertTrue(item.get_deferred_fields()) - else: - self.assertTrue(item._deferred_fields) + self.assertTrue(item.get_deferred_fields()) # has_changed() returns False for deferred fields, without un-deferring them. # Use an if because ModelTracked doesn't support has_changed() in this case. if self.tracked_class == Tracked: self.assertFalse(item.tracker.has_changed('number')) - if django.VERSION >= (1, 10): - self.assertIsInstance(item.__class__.number, DescriptorWrapper) - self.assertTrue('number' in item.get_deferred_fields()) - else: - self.assertTrue('number' in item._deferred_fields) + self.assertIsInstance(item.__class__.number, DescriptorWrapper) + self.assertTrue('number' in item.get_deferred_fields()) # previous() un-defers field and returns value self.assertEqual(item.tracker.previous('number'), 1) - if django.VERSION >= (1, 10): - self.assertNotIn('number', item.get_deferred_fields()) - else: - self.assertNotIn('number', item._deferred_fields) + self.assertNotIn('number', item.get_deferred_fields()) # examining a deferred field un-defers it item = self.tracked_class.objects.only('name').first() self.assertEqual(item.number, 1) - if django.VERSION >= (1, 10): - self.assertTrue('number' not in item.get_deferred_fields()) - else: - self.assertTrue('number' not in item._deferred_fields) + self.assertTrue('number' not in item.get_deferred_fields()) self.assertEqual(item.tracker.previous('number'), 1) self.assertFalse(item.tracker.has_changed('number')) diff --git a/tests/test_managers/test_inheritance_manager.py b/tests/test_managers/test_inheritance_manager.py index 374693e..95b7da4 100644 --- a/tests/test_managers/test_inheritance_manager.py +++ b/tests/test_managers/test_inheritance_manager.py @@ -171,15 +171,12 @@ class InheritanceManagerTests(TestCase): queryset = InheritanceManagerTestChild1.objects.values('id').filter(pk=self.child1.pk) self.assertEqual(list(queryset), [{'id': self.child1.pk}]) - @skipUnless(django.VERSION >= (1, 9, 0), "test only applies to Django 1.9+") - def test_dj19_values_list_on_select_subclasses(self): + def test_values_list_on_select_subclasses(self): """ Using `select_subclasses` in conjunction with `values_list()` raised an exception in `_get_sub_obj_recurse()` because the result of `values_list()` is either a `tuple` or primitive objects if `flat=True` is specified, because no type checking was done prior to fetching child nodes. - - Django versions below 1.9 are not affected by this bug. """ # Querysets are cast to lists to force immediate evaluation. @@ -430,7 +427,6 @@ class InheritanceManagerUsingModelsTests(TestCase): self.assertEqual([child3], list(results)) - @skipUnless(django.VERSION >= (1, 6, 0), "test only applies to Django 1.6+") def test_limit_to_specific_grandchild_class(self): grandchild1 = InheritanceManagerTestGrandChild1.objects.get() results = InheritanceManagerTestParent.objects.instance_of(InheritanceManagerTestGrandChild1) @@ -445,7 +441,6 @@ class InheritanceManagerUsingModelsTests(TestCase): self.assertEqual(set(children), set(results)) - @skipUnless(django.VERSION >= (1, 6, 0), "test only applies to Django 1.6+") def test_can_fetch_limited_class_grandchildren(self): # Not sure if this is the desired behaviour...? children = InheritanceManagerTestChild1.objects.select_subclasses() @@ -462,7 +457,6 @@ class InheritanceManagerUsingModelsTests(TestCase): self.assertEqual(set([child3] + list(children1)), set(results)) - @skipUnless(django.VERSION >= (1, 6, 0), "test only applies to Django 1.6+") def test_selecting_multiple_instance_classes_including_grandchildren(self): child3 = InheritanceManagerTestChild3.objects.create() grandchild1 = InheritanceManagerTestGrandChild1.objects.get() diff --git a/tests/test_models/test_deferred_fields.py b/tests/test_models/test_deferred_fields.py index ea8e3bd..2a1b702 100644 --- a/tests/test_models/test_deferred_fields.py +++ b/tests/test_models/test_deferred_fields.py @@ -31,15 +31,9 @@ class CustomDescriptorTests(TestCase): def test_deferred(self): instance = ModelWithCustomDescriptor.objects.only('id').get( pk=self.instance.pk) - if django.VERSION >= (1, 10): - self.assertIn('custom_field', instance.get_deferred_fields()) - else: - self.assertIn('custom_field', instance._deferred_fields) + self.assertIn('custom_field', instance.get_deferred_fields()) self.assertEqual(instance.custom_field, '1') - if django.VERSION >= (1, 10): - self.assertNotIn('custom_field', instance.get_deferred_fields()) - else: - self.assertNotIn('custom_field', instance._deferred_fields) + self.assertNotIn('custom_field', instance.get_deferred_fields()) self.assertEqual(instance.regular_field, 1) self.assertEqual(instance.tracked_custom_field, '1') self.assertEqual(instance.tracked_regular_field, 1) @@ -60,12 +54,9 @@ class CustomDescriptorTests(TestCase): self.assertEqual(instance.tracked_regular_field, 2) instance = ModelWithCustomDescriptor.objects.only('id').get(pk=instance.pk) - if django.VERSION >= (1, 10): - # This fails on 1.8 and 1.9, which is a bug in the deferred field - # implementation on those versions. - instance.tracked_custom_field = 3 - self.assertEqual(instance.tracked_custom_field, '3') - self.assertTrue(instance.tracker.has_changed('tracked_custom_field')) - del instance.tracked_custom_field - self.assertEqual(instance.tracked_custom_field, '2') - self.assertFalse(instance.tracker.has_changed('tracked_custom_field')) + instance.tracked_custom_field = 3 + self.assertEqual(instance.tracked_custom_field, '3') + self.assertTrue(instance.tracker.has_changed('tracked_custom_field')) + del instance.tracked_custom_field + self.assertEqual(instance.tracked_custom_field, '2') + self.assertFalse(instance.tracker.has_changed('tracked_custom_field')) diff --git a/translations.py b/translations.py index 8eebf95..365803e 100755 --- a/translations.py +++ b/translations.py @@ -23,10 +23,6 @@ def run(command): if not settings.configured: settings.configure(**DEFAULT_SETTINGS) - # Compatibility with Django 1.7's stricter initialization - if hasattr(django, 'setup'): - django.setup() - parent = os.path.dirname(os.path.abspath(__file__)) appdir = os.path.join(parent, 'model_utils') os.chdir(appdir)