Avoided creation of deferred model from another deferred model
Also never create deferred model when no attrs are deferred.
This commit is contained in:
parent
5b0375ec3e
commit
f7dba61881
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue