summaryrefslogtreecommitdiff
path: root/django/db/models/query_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/db/models/query_utils.py')
-rw-r--r--django/db/models/query_utils.py31
1 files changed, 19 insertions, 12 deletions
diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
index a82ed23dbb..52b472d252 100644
--- a/django/db/models/query_utils.py
+++ b/django/db/models/query_utils.py
@@ -403,8 +403,11 @@ class FilteredRelation:
self.alias = None
if not isinstance(condition, Q):
raise ValueError("condition argument must be a Q() instance.")
+ # .condition and .resolved_condition have to be stored independently
+ # as the former must remain unchanged for Join.__eq__ to remain stable
+ # and reusable even once their .filtered_relation are resolved.
self.condition = condition
- self.path = []
+ self.resolved_condition = None
def __eq__(self, other):
if not isinstance(other, self.__class__):
@@ -418,18 +421,22 @@ class FilteredRelation:
def clone(self):
clone = FilteredRelation(self.relation_name, condition=self.condition)
clone.alias = self.alias
- clone.path = self.path[:]
+ if (resolved_condition := self.resolved_condition) is not None:
+ clone.resolved_condition = resolved_condition.clone()
return clone
- def resolve_expression(self, *args, **kwargs):
- """
- QuerySet.annotate() only accepts expression-like arguments
- (with a resolve_expression() method).
- """
- raise NotImplementedError("FilteredRelation.resolve_expression() is unused.")
+ def relabeled_clone(self, change_map):
+ clone = self.clone()
+ if resolved_condition := clone.resolved_condition:
+ clone.resolved_condition = resolved_condition.relabeled_clone(change_map)
+ return clone
+
+ def resolve_expression(self, query, reuse, *args, **kwargs):
+ clone = self.clone()
+ clone.resolved_condition = query.build_filtered_relation_q(
+ self.condition, reuse=reuse
+ )
+ return clone
def as_sql(self, compiler, connection):
- # Resolve the condition in Join.filtered_relation.
- query = compiler.query
- where = query.build_filtered_relation_q(self.condition, reuse=set(self.path))
- return compiler.compile(where)
+ return compiler.compile(self.resolved_condition)