1
0
mirror of https://github.com/django/django.git synced 2025-01-03 15:06:09 +00:00

Fixed #35230 -- Added cached ForeignObjectRel.accessor_name.

This commit is contained in:
Adam Johnson 2024-02-19 04:47:12 +00:00 committed by GitHub
parent 7ba6c9edc5
commit 5e80390add
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 16 additions and 14 deletions

View File

@ -359,7 +359,7 @@ class ModelDetailView(BaseAdminDocsView):
"app_label": rel.related_model._meta.app_label, "app_label": rel.related_model._meta.app_label,
"object_name": rel.related_model._meta.object_name, "object_name": rel.related_model._meta.object_name,
} }
accessor = rel.get_accessor_name() accessor = rel.accessor_name
fields.append( fields.append(
{ {
"name": "%s.all" % accessor, "name": "%s.all" % accessor,

View File

@ -254,7 +254,7 @@ class RelatedField(FieldCacheMixin, Field):
# (so `is_hidden` returns True), then there are no clashes to check # (so `is_hidden` returns True), then there are no clashes to check
# and we can skip these fields. # and we can skip these fields.
rel_is_hidden = self.remote_field.is_hidden() rel_is_hidden = self.remote_field.is_hidden()
rel_name = self.remote_field.get_accessor_name() # i. e. "model_set" rel_name = self.remote_field.accessor_name # i. e. "model_set"
rel_query_name = self.related_query_name() # i. e. "model" rel_query_name = self.related_query_name() # i. e. "model"
# i.e. "app_label.Model.field". # i.e. "app_label.Model.field".
field_name = "%s.%s" % (opts.label, self.name) field_name = "%s.%s" % (opts.label, self.name)
@ -307,7 +307,7 @@ class RelatedField(FieldCacheMixin, Field):
clash_field.related_model._meta.label, clash_field.related_model._meta.label,
clash_field.field.name, clash_field.field.name,
) )
if not rel_is_hidden and clash_field.get_accessor_name() == rel_name: if not rel_is_hidden and clash_field.accessor_name == rel_name:
errors.append( errors.append(
checks.Error( checks.Error(
f"Reverse accessor '{rel_opts.object_name}.{rel_name}' " f"Reverse accessor '{rel_opts.object_name}.{rel_name}' "
@ -323,7 +323,7 @@ class RelatedField(FieldCacheMixin, Field):
) )
) )
if clash_field.get_accessor_name() == rel_query_name: if clash_field.accessor_name == rel_query_name:
errors.append( errors.append(
checks.Error( checks.Error(
"Reverse query name for '%s' clashes with reverse query name " "Reverse query name for '%s' clashes with reverse query name "
@ -893,7 +893,7 @@ class ForeignObject(RelatedField):
): ):
setattr( setattr(
cls._meta.concrete_model, cls._meta.concrete_model,
related.get_accessor_name(), related.accessor_name,
self.related_accessor_class(related), self.related_accessor_class(related),
) )
# While 'limit_choices_to' might be a callable, simply pass # While 'limit_choices_to' might be a callable, simply pass
@ -1947,7 +1947,7 @@ class ManyToManyField(RelatedField):
): ):
setattr( setattr(
cls, cls,
related.get_accessor_name(), related.accessor_name,
ManyToManyDescriptor(self.remote_field, reverse=True), ManyToManyDescriptor(self.remote_field, reverse=True),
) )

View File

@ -524,7 +524,7 @@ class ReverseOneToOneDescriptor:
if rel_obj is None: if rel_obj is None:
raise self.RelatedObjectDoesNotExist( raise self.RelatedObjectDoesNotExist(
"%s has no %s." "%s has no %s."
% (instance.__class__.__name__, self.related.get_accessor_name()) % (instance.__class__.__name__, self.related.accessor_name)
) )
else: else:
return rel_obj return rel_obj
@ -564,7 +564,7 @@ class ReverseOneToOneDescriptor:
% ( % (
value, value,
instance._meta.object_name, instance._meta.object_name,
self.related.get_accessor_name(), self.related.accessor_name,
self.related.related_model._meta.object_name, self.related.related_model._meta.object_name,
) )
) )
@ -652,7 +652,7 @@ class ReverseManyToOneDescriptor:
def _get_set_deprecation_msg_params(self): def _get_set_deprecation_msg_params(self):
return ( return (
"reverse side of a related set", "reverse side of a related set",
self.rel.get_accessor_name(), self.rel.accessor_name,
) )
def __set__(self, instance, value): def __set__(self, instance, value):
@ -1019,7 +1019,7 @@ class ManyToManyDescriptor(ReverseManyToOneDescriptor):
return ( return (
"%s side of a many-to-many set" "%s side of a many-to-many set"
% ("reverse" if self.reverse else "forward"), % ("reverse" if self.reverse else "forward"),
self.rel.get_accessor_name() if self.reverse else self.field.name, self.rel.accessor_name if self.reverse else self.field.name,
) )

View File

@ -219,6 +219,10 @@ class ForeignObjectRel(FieldCacheMixin):
# example custom multicolumn joins currently have no remote field). # example custom multicolumn joins currently have no remote field).
self.field_name = None self.field_name = None
@cached_property
def accessor_name(self):
return self.get_accessor_name()
def get_accessor_name(self, model=None): def get_accessor_name(self, model=None):
# This method encapsulates the logic that decides what name to give an # This method encapsulates the logic that decides what name to give an
# accessor descriptor that retrieves related many-to-one or # accessor descriptor that retrieves related many-to-one or
@ -252,7 +256,7 @@ class ForeignObjectRel(FieldCacheMixin):
Return the name of the cache key to use for storing an instance of the Return the name of the cache key to use for storing an instance of the
forward model on the reverse model. forward model on the reverse model.
""" """
return self.get_accessor_name() return self.accessor_name
class ManyToOneRel(ForeignObjectRel): class ManyToOneRel(ForeignObjectRel):

View File

@ -473,9 +473,7 @@ class OneToOneTests(TestCase):
self.assertFalse( self.assertFalse(
hasattr( hasattr(
Target, Target,
HiddenPointer._meta.get_field( HiddenPointer._meta.get_field("target").remote_field.accessor_name,
"target"
).remote_field.get_accessor_name(),
) )
) )