diff options
Diffstat (limited to 'django/db/models/sql/datastructures.py')
-rw-r--r-- | django/db/models/sql/datastructures.py | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/django/db/models/sql/datastructures.py b/django/db/models/sql/datastructures.py index 069eb1a301..46a977188a 100644 --- a/django/db/models/sql/datastructures.py +++ b/django/db/models/sql/datastructures.py @@ -61,7 +61,15 @@ class Join: self.join_type = join_type # A list of 2-tuples to use in the ON clause of the JOIN. # Each 2-tuple will create one join condition in the ON clause. - self.join_cols = join_field.get_joining_columns() + if hasattr(join_field, "get_joining_fields"): + self.join_fields = join_field.get_joining_fields() + self.join_cols = tuple( + (lhs_field.column, rhs_field.column) + for lhs_field, rhs_field in self.join_fields + ) + else: + self.join_fields = None + self.join_cols = join_field.get_joining_columns() # Along which field (or ForeignObjectRel in the reverse join case) self.join_field = join_field # Is this join nullabled? @@ -78,18 +86,21 @@ class Join: params = [] qn = compiler.quote_name_unless_alias qn2 = connection.ops.quote_name - # Add a join condition for each pair of joining columns. - for lhs_col, rhs_col in self.join_cols: - join_conditions.append( - "%s.%s = %s.%s" - % ( - qn(self.parent_alias), - qn2(lhs_col), - qn(self.table_alias), - qn2(rhs_col), + join_fields = self.join_fields or self.join_cols + for lhs, rhs in join_fields: + if isinstance(lhs, str): + lhs_full_name = "%s.%s" % (qn(self.parent_alias), qn2(lhs)) + rhs_full_name = "%s.%s" % (qn(self.table_alias), qn2(rhs)) + else: + lhs, rhs = connection.ops.prepare_join_on_clause( + self.parent_alias, lhs, self.table_alias, rhs ) - ) + lhs_sql, lhs_params = compiler.compile(lhs) + lhs_full_name = lhs_sql % lhs_params + rhs_sql, rhs_params = compiler.compile(rhs) + rhs_full_name = rhs_sql % rhs_params + join_conditions.append(f"{lhs_full_name} = {rhs_full_name}") # Add a single condition inside parentheses for whatever # get_extra_restriction() returns. |