mirror of
https://github.com/django/django.git
synced 2024-12-22 09:05:43 +00:00
Fixed #35407 -- Cached model's Options.swapped.
This commit is contained in:
parent
ceea86baa3
commit
7abe5112f4
@ -5,6 +5,7 @@ from collections import defaultdict
|
|||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
|
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
|
||||||
|
from django.core.signals import setting_changed
|
||||||
from django.db import connections
|
from django.db import connections
|
||||||
from django.db.models import AutoField, Manager, OrderWrt, UniqueConstraint
|
from django.db.models import AutoField, Manager, OrderWrt, UniqueConstraint
|
||||||
from django.db.models.query_utils import PathInfo
|
from django.db.models.query_utils import PathInfo
|
||||||
@ -230,6 +231,9 @@ class Options:
|
|||||||
self.db_table, connection.ops.max_name_length()
|
self.db_table, connection.ops.max_name_length()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.swappable:
|
||||||
|
setting_changed.connect(self.setting_changed)
|
||||||
|
|
||||||
def _format_names(self, objs):
|
def _format_names(self, objs):
|
||||||
"""App label/class name interpolation for object names."""
|
"""App label/class name interpolation for object names."""
|
||||||
names = {"app_label": self.app_label.lower(), "class": self.model_name}
|
names = {"app_label": self.app_label.lower(), "class": self.model_name}
|
||||||
@ -399,7 +403,7 @@ class Options:
|
|||||||
with override(None):
|
with override(None):
|
||||||
return str(self.verbose_name)
|
return str(self.verbose_name)
|
||||||
|
|
||||||
@property
|
@cached_property
|
||||||
def swapped(self):
|
def swapped(self):
|
||||||
"""
|
"""
|
||||||
Has this model been swapped out for another? If so, return the model
|
Has this model been swapped out for another? If so, return the model
|
||||||
@ -427,6 +431,10 @@ class Options:
|
|||||||
return swapped_for
|
return swapped_for
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def setting_changed(self, *, setting, **kwargs):
|
||||||
|
if setting == self.swappable and "swapped" in self.__dict__:
|
||||||
|
del self.swapped
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def managers(self):
|
def managers(self):
|
||||||
managers = []
|
managers = []
|
||||||
|
@ -166,6 +166,11 @@ class Relating(models.Model):
|
|||||||
people_hidden = models.ManyToManyField(Person, related_name="+")
|
people_hidden = models.ManyToManyField(Person, related_name="+")
|
||||||
|
|
||||||
|
|
||||||
|
class Swappable(models.Model):
|
||||||
|
class Meta:
|
||||||
|
swappable = "MODEL_META_TESTS_SWAPPED"
|
||||||
|
|
||||||
|
|
||||||
# ParentListTests models
|
# ParentListTests models
|
||||||
class CommonAncestor(models.Model):
|
class CommonAncestor(models.Model):
|
||||||
pass
|
pass
|
||||||
|
@ -3,7 +3,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelatio
|
|||||||
from django.core.exceptions import FieldDoesNotExist
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
from django.db.models import CharField, Field, ForeignObjectRel, ManyToManyField
|
from django.db.models import CharField, Field, ForeignObjectRel, ManyToManyField
|
||||||
from django.db.models.options import EMPTY_RELATION_TREE, IMMUTABLE_WARNING
|
from django.db.models.options import EMPTY_RELATION_TREE, IMMUTABLE_WARNING
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase, override_settings
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
AbstractPerson,
|
AbstractPerson,
|
||||||
@ -16,6 +16,7 @@ from .models import (
|
|||||||
Relating,
|
Relating,
|
||||||
Relation,
|
Relation,
|
||||||
SecondParent,
|
SecondParent,
|
||||||
|
Swappable,
|
||||||
)
|
)
|
||||||
from .results import TEST_RESULTS
|
from .results import TEST_RESULTS
|
||||||
|
|
||||||
@ -233,6 +234,31 @@ class VerboseNameRawTests(SimpleTestCase):
|
|||||||
self.assertEqual(Person._meta.verbose_name_raw, "Person")
|
self.assertEqual(Person._meta.verbose_name_raw, "Person")
|
||||||
|
|
||||||
|
|
||||||
|
class SwappedTests(SimpleTestCase):
|
||||||
|
def test_plain_model_none(self):
|
||||||
|
self.assertIsNone(Relation._meta.swapped)
|
||||||
|
|
||||||
|
def test_unset(self):
|
||||||
|
self.assertIsNone(Swappable._meta.swapped)
|
||||||
|
|
||||||
|
def test_set_and_unset(self):
|
||||||
|
with override_settings(MODEL_META_TESTS_SWAPPED="model_meta.Relation"):
|
||||||
|
self.assertEqual(Swappable._meta.swapped, "model_meta.Relation")
|
||||||
|
self.assertIsNone(Swappable._meta.swapped)
|
||||||
|
|
||||||
|
def test_setting_none(self):
|
||||||
|
with override_settings(MODEL_META_TESTS_SWAPPED=None):
|
||||||
|
self.assertIsNone(Swappable._meta.swapped)
|
||||||
|
|
||||||
|
def test_setting_non_label(self):
|
||||||
|
with override_settings(MODEL_META_TESTS_SWAPPED="not-a-label"):
|
||||||
|
self.assertEqual(Swappable._meta.swapped, "not-a-label")
|
||||||
|
|
||||||
|
def test_setting_self(self):
|
||||||
|
with override_settings(MODEL_META_TESTS_SWAPPED="model_meta.swappable"):
|
||||||
|
self.assertIsNone(Swappable._meta.swapped)
|
||||||
|
|
||||||
|
|
||||||
class RelationTreeTests(SimpleTestCase):
|
class RelationTreeTests(SimpleTestCase):
|
||||||
all_models = (Relation, AbstractPerson, BasePerson, Person, ProxyPerson, Relating)
|
all_models = (Relation, AbstractPerson, BasePerson, Person, ProxyPerson, Relating)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user