summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Hartmann <julien@etherdream.org>2016-06-23 17:10:52 +0700
committerTim Graham <timograham@gmail.com>2016-07-11 13:30:44 -0400
commitf4afb85d7e900123fa8f88110adc011ab184e153 (patch)
treec917ef85c486c4f399ea1076178b7034eb7fcbb5
parent418658f453bed7fe7949dda26651aab370003e6a (diff)
Fixed #26749 -- Preserved behavior of use_for_related_field during deprecation.
-rw-r--r--django/db/models/fields/related_descriptors.py6
-rw-r--r--docs/releases/1.10.txt6
-rw-r--r--tests/managers_regress/tests.py97
3 files changed, 102 insertions, 7 deletions
diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py
index c217b9b2b0..de36d4a8e5 100644
--- a/django/db/models/fields/related_descriptors.py
+++ b/django/db/models/fields/related_descriptors.py
@@ -109,8 +109,7 @@ class ForwardManyToOneDescriptor(object):
def get_queryset(self, **hints):
related_model = self.field.remote_field.model
- if (not related_model._meta.base_manager_name and
- getattr(related_model._default_manager, 'use_for_related_fields', False)):
+ if getattr(related_model._default_manager, 'use_for_related_fields', False):
if not getattr(related_model._default_manager, 'silence_use_for_related_fields_deprecation', False):
warnings.warn(
"use_for_related_fields is deprecated, instead "
@@ -326,8 +325,7 @@ class ReverseOneToOneDescriptor(object):
def get_queryset(self, **hints):
related_model = self.related.related_model
- if (not related_model._meta.base_manager_name and
- getattr(related_model._default_manager, 'use_for_related_fields', False)):
+ if getattr(related_model._default_manager, 'use_for_related_fields', False):
if not getattr(related_model._default_manager, 'silence_use_for_related_fields_deprecation', False):
warnings.warn(
"use_for_related_fields is deprecated, instead "
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index c56ac6efc6..b7b2813b31 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -1091,6 +1091,12 @@ class to override the manager from the concrete model, or you'll set the
model's ``Meta.manager_inheritance_from_future=True`` option to opt-in to the
new inheritance behavior.
+During the deprecation period, ``use_for_related_fields`` will be honored and
+raise a warning, even if a ``base_manager_name`` is set. This allows
+third-party code to preserve legacy behavior while transitioning to the new
+API. The warning can be silenced by setting
+``silence_use_for_related_fields_deprecation=True`` on the manager.
+
Miscellaneous
-------------
diff --git a/tests/managers_regress/tests.py b/tests/managers_regress/tests.py
index 7c1223a5f1..feaca1cba0 100644
--- a/tests/managers_regress/tests.py
+++ b/tests/managers_regress/tests.py
@@ -334,11 +334,26 @@ class TestManagerDeprecations(TestCase):
self.assertEqual(len(warns), 0)
def test_use_for_related_fields_for_many_to_one(self):
+ # Common objects
+ class MyManagerQuerySet(models.QuerySet):
+ pass
+
+ class MyLegacyManagerQuerySet(models.QuerySet):
+ pass
+
class MyManager(models.Manager):
+ def get_queryset(self):
+ return MyManagerQuerySet(model=self.model, using=self._db, hints=self._hints)
+
+ class MyLegacyManager(models.Manager):
use_for_related_fields = True
+ def get_queryset(self):
+ return MyLegacyManagerQuerySet(model=self.model, using=self._db, hints=self._hints)
+
+ # With legacy config there should be a deprecation warning
class MyRelModel(models.Model):
- objects = MyManager()
+ objects = MyLegacyManager()
class MyModel(models.Model):
fk = models.ForeignKey(MyRelModel, on_delete=models.DO_NOTHING)
@@ -375,16 +390,61 @@ class TestManagerDeprecations(TestCase):
pass
self.assertEqual(len(warns), 0)
+ # When mixing base_manager_name and use_for_related_fields, there
+ # should be warnings.
+ class MyRelModel3(models.Model):
+ my_base_manager = MyManager()
+ my_default_manager = MyLegacyManager()
+
+ class Meta:
+ base_manager_name = 'my_base_manager'
+ default_manager_name = 'my_default_manager'
+
+ class MyModel3(models.Model):
+ fk = models.ForeignKey(MyRelModel3, on_delete=models.DO_NOTHING)
+
+ with warnings.catch_warnings(record=True) as warns:
+ warnings.simplefilter('always', RemovedInDjango20Warning)
+ try:
+ MyModel3(fk_id=42).fk
+ except DatabaseError:
+ pass
+ self.assertEqual(len(warns), 1)
+ self.assertEqual(
+ str(warns[0].message),
+ "use_for_related_fields is deprecated, "
+ "instead set Meta.base_manager_name on "
+ "'managers_regress.MyRelModel3'.",
+ )
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter('always', RemovedInDjango20Warning)
+ self.assertIsInstance(MyModel3.fk.get_queryset(), MyLegacyManagerQuerySet)
+
def test_use_for_related_fields_for_one_to_one(self):
+ # Common objects
+ class MyManagerQuerySet(models.QuerySet):
+ pass
+
+ class MyLegacyManagerQuerySet(models.QuerySet):
+ pass
+
class MyManager(models.Manager):
+ def get_queryset(self):
+ return MyManagerQuerySet(model=self.model, using=self._db, hints=self._hints)
+
+ class MyLegacyManager(models.Manager):
use_for_related_fields = True
+ def get_queryset(self):
+ return MyLegacyManagerQuerySet(model=self.model, using=self._db, hints=self._hints)
+
+ # With legacy config there should be a deprecation warning
class MyRelModel(models.Model):
- objects = MyManager()
+ objects = MyLegacyManager()
class MyModel(models.Model):
o2o = models.OneToOneField(MyRelModel, on_delete=models.DO_NOTHING)
- objects = MyManager()
+ objects = MyLegacyManager()
with warnings.catch_warnings(record=True) as warns:
warnings.simplefilter('always', RemovedInDjango20Warning)
@@ -440,6 +500,37 @@ class TestManagerDeprecations(TestCase):
pass
self.assertEqual(len(warns), 0)
+ # When mixing base_manager_name and use_for_related_fields, there
+ # should be warnings.
+ class MyRelModel3(models.Model):
+ my_base_manager = MyManager()
+ my_default_manager = MyLegacyManager()
+
+ class Meta:
+ base_manager_name = 'my_base_manager'
+ default_manager_name = 'my_default_manager'
+
+ class MyModel3(models.Model):
+ o2o = models.OneToOneField(MyRelModel3, on_delete=models.DO_NOTHING)
+
+ with warnings.catch_warnings(record=True) as warns:
+ warnings.simplefilter('always', RemovedInDjango20Warning)
+ try:
+ MyModel3(o2o_id=42).o2o
+ except DatabaseError:
+ pass
+
+ self.assertEqual(len(warns), 1)
+ self.assertEqual(
+ str(warns[0].message),
+ "use_for_related_fields is deprecated, "
+ "instead set Meta.base_manager_name on "
+ "'managers_regress.MyRelModel3'.",
+ )
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter('always', RemovedInDjango20Warning)
+ self.assertIsInstance(MyModel3.o2o.get_queryset(), MyLegacyManagerQuerySet)
+
def test_legacy_objects_is_created(self):
class ConcreteParentWithoutManager(models.Model):
pass