1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

[4.1.x] Fixed #33984 -- Reverted "Fixed #32980 -- Made models cache related managers."

This reverts 4f8c7fd9d9 and adds
two regression tests:
- test_related_manager_refresh(), and
- test_create_copy_with_m2m().

Thanks joeli for the report.
Backport of 5e0aa362d9 from main
This commit is contained in:
Mariusz Felisiak
2022-09-30 18:18:33 +02:00
parent ecf6506f44
commit 7a1675806a
12 changed files with 47 additions and 176 deletions

View File

@@ -552,14 +552,6 @@ class ReverseGenericManyToOneDescriptor(ReverseManyToOneDescriptor):
self.rel,
)
@cached_property
def related_manager_cache_key(self):
# By default, GenericRel instances will be marked as hidden unless
# related_query_name is given (their accessor name being "+" when
# hidden), which would cause multiple GenericRelations declared on a
# single model to collide, so always use the remote field's name.
return self.field.get_cache_name()
def create_generic_related_manager(superclass, rel):
"""

View File

@@ -434,18 +434,11 @@ class ModelBase(type):
return cls._meta.default_manager
class ModelStateCacheDescriptor:
"""
Upon first access, replace itself with an empty dictionary on the instance.
"""
def __set_name__(self, owner, name):
self.attribute_name = name
class ModelStateFieldsCacheDescriptor:
def __get__(self, instance, cls=None):
if instance is None:
return self
res = instance.__dict__[self.attribute_name] = {}
res = instance.fields_cache = {}
return res
@@ -458,20 +451,7 @@ class ModelState:
# explicit (non-auto) PKs. This impacts validation only; it has no effect
# on the actual save.
adding = True
fields_cache = ModelStateCacheDescriptor()
related_managers_cache = ModelStateCacheDescriptor()
def __getstate__(self):
state = self.__dict__.copy()
if "fields_cache" in state:
state["fields_cache"] = self.fields_cache.copy()
# Manager instances stored in related_managers_cache won't necessarily
# be deserializable if they were dynamically created via an inner
# scope, e.g. create_forward_many_to_many_manager() and
# create_generic_related_manager().
if "related_managers_cache" in state:
state["related_managers_cache"] = {}
return state
fields_cache = ModelStateFieldsCacheDescriptor()
class Model(metaclass=ModelBase):
@@ -633,6 +613,7 @@ class Model(metaclass=ModelBase):
"""Hook to allow choosing the attributes to pickle."""
state = self.__dict__.copy()
state["_state"] = copy.copy(state["_state"])
state["_state"].fields_cache = state["_state"].fields_cache.copy()
# memoryview cannot be pickled, so cast it to bytes and store
# separately.
_memoryview_attrs = []

View File

@@ -561,14 +561,6 @@ class ReverseManyToOneDescriptor:
self.rel = rel
self.field = rel.field
@cached_property
def related_manager_cache_key(self):
# Being able to access the manager instance precludes it from being
# hidden. The rel's accessor name is used to allow multiple managers
# to the same model to coexist. e.g. post.attached_comment_set and
# post.attached_link_set are separately cached.
return self.rel.get_cache_name()
@cached_property
def related_manager_cls(self):
related_model = self.rel.related_model
@@ -590,11 +582,8 @@ class ReverseManyToOneDescriptor:
"""
if instance is None:
return self
key = self.related_manager_cache_key
instance_cache = instance._state.related_managers_cache
if key not in instance_cache:
instance_cache[key] = self.related_manager_cls(instance)
return instance_cache[key]
return self.related_manager_cls(instance)
def _get_set_deprecation_msg_params(self):
return (
@@ -913,17 +902,6 @@ class ManyToManyDescriptor(ReverseManyToOneDescriptor):
reverse=self.reverse,
)
@cached_property
def related_manager_cache_key(self):
if self.reverse:
# Symmetrical M2Ms won't have an accessor name, but should never
# end up in the reverse branch anyway, as the related_name ends up
# being hidden, and no public manager is created.
return self.rel.get_cache_name()
else:
# For forward managers, defer to the field name.
return self.field.get_cache_name()
def _get_set_deprecation_msg_params(self):
return (
"%s side of a many-to-many set"