diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index c20de5995a3..9ee2d65c8af 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -14,7 +14,7 @@ from django.db.models import fields from django.db.models.constants import LOOKUP_SEP from django.db.models.query_utils import Q from django.utils.deconstruct import deconstructible -from django.utils.functional import cached_property +from django.utils.functional import cached_property, classproperty from django.utils.hashable import make_hashable @@ -485,13 +485,18 @@ class BaseExpression: class Expression(BaseExpression, Combinable): """An expression that can be combined with other expressions.""" + @classproperty + @functools.lru_cache(maxsize=128) + def _constructor_signature(cls): + return inspect.signature(cls.__init__) + @cached_property def identity(self): - constructor_signature = inspect.signature(self.__init__) args, kwargs = self._constructor_args - signature = constructor_signature.bind_partial(*args, **kwargs) + signature = self._constructor_signature.bind_partial(self, *args, **kwargs) signature.apply_defaults() - arguments = signature.arguments.items() + arguments = iter(signature.arguments.items()) + next(arguments) identity = [self.__class__] for arg, value in arguments: if isinstance(value, fields.Field):