mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Avoided creation of deferred model from another deferred model
Also never create deferred model when no attrs are deferred.
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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 ( | ||||
| @@ -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',)) | ||||
| @@ -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): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user