diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py index 5c18d676f2..38a2bb9286 100644 --- a/django/contrib/admindocs/views.py +++ b/django/contrib/admindocs/views.py @@ -359,7 +359,7 @@ class ModelDetailView(BaseAdminDocsView): "app_label": rel.related_model._meta.app_label, "object_name": rel.related_model._meta.object_name, } - accessor = rel.get_accessor_name() + accessor = rel.accessor_name fields.append( { "name": "%s.all" % accessor, diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 8564e6366b..1628e46d2c 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -254,7 +254,7 @@ class RelatedField(FieldCacheMixin, Field): # (so `is_hidden` returns True), then there are no clashes to check # and we can skip these fields. 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" # i.e. "app_label.Model.field". field_name = "%s.%s" % (opts.label, self.name) @@ -307,7 +307,7 @@ class RelatedField(FieldCacheMixin, Field): clash_field.related_model._meta.label, 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( checks.Error( 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( checks.Error( "Reverse query name for '%s' clashes with reverse query name " @@ -893,7 +893,7 @@ class ForeignObject(RelatedField): ): setattr( cls._meta.concrete_model, - related.get_accessor_name(), + related.accessor_name, self.related_accessor_class(related), ) # While 'limit_choices_to' might be a callable, simply pass @@ -1947,7 +1947,7 @@ class ManyToManyField(RelatedField): ): setattr( cls, - related.get_accessor_name(), + related.accessor_name, ManyToManyDescriptor(self.remote_field, reverse=True), ) diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index a8f298230a..9269cdb100 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -524,7 +524,7 @@ class ReverseOneToOneDescriptor: if rel_obj is None: raise self.RelatedObjectDoesNotExist( "%s has no %s." - % (instance.__class__.__name__, self.related.get_accessor_name()) + % (instance.__class__.__name__, self.related.accessor_name) ) else: return rel_obj @@ -564,7 +564,7 @@ class ReverseOneToOneDescriptor: % ( value, instance._meta.object_name, - self.related.get_accessor_name(), + self.related.accessor_name, self.related.related_model._meta.object_name, ) ) @@ -652,7 +652,7 @@ class ReverseManyToOneDescriptor: def _get_set_deprecation_msg_params(self): return ( "reverse side of a related set", - self.rel.get_accessor_name(), + self.rel.accessor_name, ) def __set__(self, instance, value): @@ -1019,7 +1019,7 @@ class ManyToManyDescriptor(ReverseManyToOneDescriptor): return ( "%s side of a many-to-many set" % ("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, ) diff --git a/django/db/models/fields/reverse_related.py b/django/db/models/fields/reverse_related.py index 144cce6142..9d357a3948 100644 --- a/django/db/models/fields/reverse_related.py +++ b/django/db/models/fields/reverse_related.py @@ -219,6 +219,10 @@ class ForeignObjectRel(FieldCacheMixin): # example custom multicolumn joins currently have no remote field). self.field_name = None + @cached_property + def accessor_name(self): + return self.get_accessor_name() + def get_accessor_name(self, model=None): # This method encapsulates the logic that decides what name to give an # 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 forward model on the reverse model. """ - return self.get_accessor_name() + return self.accessor_name class ManyToOneRel(ForeignObjectRel): diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py index 83644871fe..280a8273fb 100644 --- a/tests/one_to_one/tests.py +++ b/tests/one_to_one/tests.py @@ -473,9 +473,7 @@ class OneToOneTests(TestCase): self.assertFalse( hasattr( Target, - HiddenPointer._meta.get_field( - "target" - ).remote_field.get_accessor_name(), + HiddenPointer._meta.get_field("target").remote_field.accessor_name, ) )