Remove unsupported django version hacks.

This commit is contained in:
Rémy HUBSCHER 2019-08-21 11:02:23 +02:00
parent 82dfed6a84
commit e6c7b567d1
No known key found for this signature in database
GPG key ID: 82B47F36036A312A
9 changed files with 29 additions and 118 deletions

View file

@ -81,9 +81,7 @@ class StatusField(models.CharField):
assert hasattr(sender, self.choices_name), \ assert hasattr(sender, self.choices_name), \
"To use StatusField, the model '%s' must have a %s choices class attribute." \ "To use StatusField, the model '%s' must have a %s choices class attribute." \
% (sender.__name__, self.choices_name) % (sender.__name__, self.choices_name)
self._choices = getattr(sender, self.choices_name) self.choices = getattr(sender, self.choices_name)
if django.VERSION >= (1, 9, 0):
self.choices = self._choices
if not self.has_default(): if not self.has_default():
self.default = tuple(getattr(sender, self.choices_name))[0][0] # set first as 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 # 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 # 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 # choices now so the super method will add the get_FOO_display method
self._choices = [(0, 'dummy')] self.choices = [(0, 'dummy')]
if django.VERSION >= (1, 9, 0):
self.choices = self._choices
super(StatusField, self).contribute_to_class(cls, name) super(StatusField, self).contribute_to_class(cls, name)
def deconstruct(self): def deconstruct(self):
@ -133,11 +129,10 @@ class MonitorField(models.DateTimeField):
return getattr(instance, self.monitor) return getattr(instance, self.monitor)
def _save_initial(self, sender, instance, **kwargs): 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 # Fix related to issue #241 to avoid recursive error on double monitor fields
return return
setattr(instance, self.monitor_attname, setattr(instance, self.monitor_attname, self.get_monitored_value(instance))
self.get_monitored_value(instance))
def pre_save(self, model_instance, add): def pre_save(self, model_instance, add):
value = now() value = now()

View file

@ -114,35 +114,6 @@ class InheritanceQuerySetMixin(object):
qset._annotated = [a.default_alias for a in args] + list(kwargs.keys()) qset._annotated = [a.default_alias for a in args] + list(kwargs.keys())
return qset 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): def _get_subclasses_recurse(self, model, levels=None):
""" """
Given a Model class, find all related objects, exploring children 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): def _get_sub_obj_recurse(self, obj, s):
rel, _, s = s.partition(LOOKUP_SEP) 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: try:
node = getattr(obj, rel) node = getattr(obj, rel)
except ObjectDoesNotExist: except ObjectDoesNotExist:

View file

@ -18,11 +18,7 @@ from model_utils.managers import (
SoftDeletableManager, SoftDeletableManager,
) )
if django.VERSION >= (1, 9, 0): from django.utils.timezone import now
from django.db.models.functions import Now
now = Now()
else:
from django.utils.timezone import now
class TimeStampedModel(models.Model): class TimeStampedModel(models.Model):
@ -75,9 +71,7 @@ def add_status_query_managers(sender, **kwargs):
if not issubclass(sender, StatusModel): if not issubclass(sender, StatusModel):
return return
if django.VERSION >= (1, 10): default_manager = sender._meta.default_manager
# First, get current manager name...
default_manager = sender._meta.default_manager
for value, display in getattr(sender, 'STATUS', ()): for value, display in getattr(sender, 'STATUS', ()):
if _field_exists(sender, value): if _field_exists(sender, value):
@ -88,9 +82,7 @@ def add_status_query_managers(sender, **kwargs):
) )
sender.add_to_class(value, QueryManager(status=value)) sender.add_to_class(value, QueryManager(status=value))
if django.VERSION >= (1, 10): sender._meta.default_manager_name = default_manager.name
# ...then, put it back, as add_to_class is modifying the default manager!
sender._meta.default_manager_name = default_manager.name
def add_timeframed_query_manager(sender, **kwargs): def add_timeframed_query_manager(sender, **kwargs):

View file

@ -93,8 +93,6 @@ class FieldInstanceTracker(object):
self.instance = instance self.instance = instance
self.fields = fields self.fields = fields
self.field_map = field_map self.field_map = field_map
if django.VERSION < (1, 10):
self.init_deferred_fields()
@property @property
def deferred_fields(self): def deferred_fields(self):

View file

@ -22,22 +22,13 @@ def mutable_to_db(value):
return str(value) return str(value)
if django.VERSION >= (1, 9, 0): class MutableField(models.TextField):
class MutableField(models.TextField): def to_python(self, value):
def to_python(self, value): return mutable_from_db(value)
return mutable_from_db(value)
def from_db_value(self, value, expression, connection, context): def from_db_value(self, value, expression, connection, context):
return mutable_from_db(value) return mutable_from_db(value)
def get_db_prep_save(self, value, connection): def get_db_prep_save(self, value, connection):
value = super(MutableField, self).get_db_prep_save(value, connection) value = super(MutableField, self).get_db_prep_save(value, connection)
return mutable_to_db(value) 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)

View file

@ -185,35 +185,23 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests):
self.instance.number = 1 self.instance.number = 1
self.instance.save() self.instance.save()
item = self.tracked_class.objects.only('name').first() item = self.tracked_class.objects.only('name').first()
if django.VERSION >= (1, 10): self.assertTrue(item.get_deferred_fields())
self.assertTrue(item.get_deferred_fields())
else:
self.assertTrue(item._deferred_fields)
# has_changed() returns False for deferred fields, without un-deferring them. # has_changed() returns False for deferred fields, without un-deferring them.
# Use an if because ModelTracked doesn't support has_changed() in this case. # Use an if because ModelTracked doesn't support has_changed() in this case.
if self.tracked_class == Tracked: if self.tracked_class == Tracked:
self.assertFalse(item.tracker.has_changed('number')) self.assertFalse(item.tracker.has_changed('number'))
if django.VERSION >= (1, 10): self.assertIsInstance(item.__class__.number, DescriptorWrapper)
self.assertIsInstance(item.__class__.number, DescriptorWrapper) self.assertTrue('number' in item.get_deferred_fields())
self.assertTrue('number' in item.get_deferred_fields())
else:
self.assertTrue('number' in item._deferred_fields)
# previous() un-defers field and returns value # previous() un-defers field and returns value
self.assertEqual(item.tracker.previous('number'), 1) self.assertEqual(item.tracker.previous('number'), 1)
if django.VERSION >= (1, 10): self.assertNotIn('number', item.get_deferred_fields())
self.assertNotIn('number', item.get_deferred_fields())
else:
self.assertNotIn('number', item._deferred_fields)
# examining a deferred field un-defers it # examining a deferred field un-defers it
item = self.tracked_class.objects.only('name').first() item = self.tracked_class.objects.only('name').first()
self.assertEqual(item.number, 1) self.assertEqual(item.number, 1)
if django.VERSION >= (1, 10): self.assertTrue('number' not in item.get_deferred_fields())
self.assertTrue('number' not in item.get_deferred_fields())
else:
self.assertTrue('number' not in item._deferred_fields)
self.assertEqual(item.tracker.previous('number'), 1) self.assertEqual(item.tracker.previous('number'), 1)
self.assertFalse(item.tracker.has_changed('number')) self.assertFalse(item.tracker.has_changed('number'))

View file

@ -171,15 +171,12 @@ class InheritanceManagerTests(TestCase):
queryset = InheritanceManagerTestChild1.objects.values('id').filter(pk=self.child1.pk) queryset = InheritanceManagerTestChild1.objects.values('id').filter(pk=self.child1.pk)
self.assertEqual(list(queryset), [{'id': 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_values_list_on_select_subclasses(self):
def test_dj19_values_list_on_select_subclasses(self):
""" """
Using `select_subclasses` in conjunction with `values_list()` raised an Using `select_subclasses` in conjunction with `values_list()` raised an
exception in `_get_sub_obj_recurse()` because the result of `values_list()` exception in `_get_sub_obj_recurse()` because the result of `values_list()`
is either a `tuple` or primitive objects if `flat=True` is specified, is either a `tuple` or primitive objects if `flat=True` is specified,
because no type checking was done prior to fetching child nodes. 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. # Querysets are cast to lists to force immediate evaluation.
@ -430,7 +427,6 @@ class InheritanceManagerUsingModelsTests(TestCase):
self.assertEqual([child3], list(results)) 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): def test_limit_to_specific_grandchild_class(self):
grandchild1 = InheritanceManagerTestGrandChild1.objects.get() grandchild1 = InheritanceManagerTestGrandChild1.objects.get()
results = InheritanceManagerTestParent.objects.instance_of(InheritanceManagerTestGrandChild1) results = InheritanceManagerTestParent.objects.instance_of(InheritanceManagerTestGrandChild1)
@ -445,7 +441,6 @@ class InheritanceManagerUsingModelsTests(TestCase):
self.assertEqual(set(children), set(results)) 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): def test_can_fetch_limited_class_grandchildren(self):
# Not sure if this is the desired behaviour...? # Not sure if this is the desired behaviour...?
children = InheritanceManagerTestChild1.objects.select_subclasses() children = InheritanceManagerTestChild1.objects.select_subclasses()
@ -462,7 +457,6 @@ class InheritanceManagerUsingModelsTests(TestCase):
self.assertEqual(set([child3] + list(children1)), set(results)) 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): def test_selecting_multiple_instance_classes_including_grandchildren(self):
child3 = InheritanceManagerTestChild3.objects.create() child3 = InheritanceManagerTestChild3.objects.create()
grandchild1 = InheritanceManagerTestGrandChild1.objects.get() grandchild1 = InheritanceManagerTestGrandChild1.objects.get()

View file

@ -31,15 +31,9 @@ class CustomDescriptorTests(TestCase):
def test_deferred(self): def test_deferred(self):
instance = ModelWithCustomDescriptor.objects.only('id').get( instance = ModelWithCustomDescriptor.objects.only('id').get(
pk=self.instance.pk) pk=self.instance.pk)
if django.VERSION >= (1, 10): self.assertIn('custom_field', instance.get_deferred_fields())
self.assertIn('custom_field', instance.get_deferred_fields())
else:
self.assertIn('custom_field', instance._deferred_fields)
self.assertEqual(instance.custom_field, '1') self.assertEqual(instance.custom_field, '1')
if django.VERSION >= (1, 10): self.assertNotIn('custom_field', instance.get_deferred_fields())
self.assertNotIn('custom_field', instance.get_deferred_fields())
else:
self.assertNotIn('custom_field', instance._deferred_fields)
self.assertEqual(instance.regular_field, 1) self.assertEqual(instance.regular_field, 1)
self.assertEqual(instance.tracked_custom_field, '1') self.assertEqual(instance.tracked_custom_field, '1')
self.assertEqual(instance.tracked_regular_field, 1) self.assertEqual(instance.tracked_regular_field, 1)
@ -60,12 +54,9 @@ class CustomDescriptorTests(TestCase):
self.assertEqual(instance.tracked_regular_field, 2) self.assertEqual(instance.tracked_regular_field, 2)
instance = ModelWithCustomDescriptor.objects.only('id').get(pk=instance.pk) instance = ModelWithCustomDescriptor.objects.only('id').get(pk=instance.pk)
if django.VERSION >= (1, 10): instance.tracked_custom_field = 3
# This fails on 1.8 and 1.9, which is a bug in the deferred field self.assertEqual(instance.tracked_custom_field, '3')
# implementation on those versions. self.assertTrue(instance.tracker.has_changed('tracked_custom_field'))
instance.tracked_custom_field = 3 del instance.tracked_custom_field
self.assertEqual(instance.tracked_custom_field, '3') self.assertEqual(instance.tracked_custom_field, '2')
self.assertTrue(instance.tracker.has_changed('tracked_custom_field')) self.assertFalse(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'))

View file

@ -23,10 +23,6 @@ def run(command):
if not settings.configured: if not settings.configured:
settings.configure(**DEFAULT_SETTINGS) 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__)) parent = os.path.dirname(os.path.abspath(__file__))
appdir = os.path.join(parent, 'model_utils') appdir = os.path.join(parent, 'model_utils')
os.chdir(appdir) os.chdir(appdir)