Loading django/db/models/query_utils.py +8 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,14 @@ def deferred_class_factory(model, attrs): being replaced with DeferredAttribute objects. The "pk_value" ties the deferred attributes to a particular instance of the model. """ if not attrs: return model # Never create deferred models based on deferred model if model._deferred: # Deferred models are proxies for the non-deferred model. We never # create chains of defers => proxy_for_model is the non-deferred # model. model = model._meta.proxy_for_model # The app registry wants a unique name for each model, otherwise the new # class won't be created (we get an exception). Therefore, we generate # the name using the passed in attrs. It's OK to reuse an existing class Loading tests/defer_regress/tests.py +12 −1 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ from django.apps import apps from django.contrib.contenttypes.models import ContentType from django.contrib.sessions.backends.db import SessionStore from django.db.models import Count from django.db.models.query_utils import deferred_class_factory, DeferredAttribute from django.test import TestCase, override_settings from .models import ( Loading Loading @@ -233,7 +234,6 @@ class DeferRegressionTest(TestCase): self.assertEqual(len(qs), 1) def test_deferred_class_factory(self): from django.db.models.query_utils import deferred_class_factory new_class = deferred_class_factory( Item, ('this_is_some_very_long_attribute_name_so_modelname_truncation_is_triggered',)) Loading @@ -241,6 +241,17 @@ class DeferRegressionTest(TestCase): new_class.__name__, 'Item_Deferred_this_is_some_very_long_attribute_nac34b1f495507dad6b02e2cb235c875e') def test_deferred_class_factory_already_deferred(self): deferred_item1 = deferred_class_factory(Item, ('name',)) deferred_item2 = deferred_class_factory(deferred_item1, ('value',)) self.assertIs(deferred_item2._meta.proxy_for_model, Item) self.assertFalse(isinstance(deferred_item2.__dict__.get('name'), DeferredAttribute)) self.assertTrue(isinstance(deferred_item2.__dict__.get('value'), DeferredAttribute)) def test_deferred_class_factory_no_attrs(self): deferred_cls = deferred_class_factory(Item, ()) self.assertFalse(deferred_cls._deferred) class DeferAnnotateSelectRelatedTest(TestCase): def test_defer_annotate_select_related(self): Loading Loading
django/db/models/query_utils.py +8 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,14 @@ def deferred_class_factory(model, attrs): being replaced with DeferredAttribute objects. The "pk_value" ties the deferred attributes to a particular instance of the model. """ if not attrs: return model # Never create deferred models based on deferred model if model._deferred: # Deferred models are proxies for the non-deferred model. We never # create chains of defers => proxy_for_model is the non-deferred # model. model = model._meta.proxy_for_model # The app registry wants a unique name for each model, otherwise the new # class won't be created (we get an exception). Therefore, we generate # the name using the passed in attrs. It's OK to reuse an existing class Loading
tests/defer_regress/tests.py +12 −1 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ from django.apps import apps from django.contrib.contenttypes.models import ContentType from django.contrib.sessions.backends.db import SessionStore from django.db.models import Count from django.db.models.query_utils import deferred_class_factory, DeferredAttribute from django.test import TestCase, override_settings from .models import ( Loading Loading @@ -233,7 +234,6 @@ class DeferRegressionTest(TestCase): self.assertEqual(len(qs), 1) def test_deferred_class_factory(self): from django.db.models.query_utils import deferred_class_factory new_class = deferred_class_factory( Item, ('this_is_some_very_long_attribute_name_so_modelname_truncation_is_triggered',)) Loading @@ -241,6 +241,17 @@ class DeferRegressionTest(TestCase): new_class.__name__, 'Item_Deferred_this_is_some_very_long_attribute_nac34b1f495507dad6b02e2cb235c875e') def test_deferred_class_factory_already_deferred(self): deferred_item1 = deferred_class_factory(Item, ('name',)) deferred_item2 = deferred_class_factory(deferred_item1, ('value',)) self.assertIs(deferred_item2._meta.proxy_for_model, Item) self.assertFalse(isinstance(deferred_item2.__dict__.get('name'), DeferredAttribute)) self.assertTrue(isinstance(deferred_item2.__dict__.get('value'), DeferredAttribute)) def test_deferred_class_factory_no_attrs(self): deferred_cls = deferred_class_factory(Item, ()) self.assertFalse(deferred_cls._deferred) class DeferAnnotateSelectRelatedTest(TestCase): def test_defer_annotate_select_related(self): Loading