diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index e91de27876..2a5a374065 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1342,6 +1342,16 @@ class ForeignObjectRel(object): def get_prep_lookup(self, lookup_name, value): return self.field.get_prep_lookup(lookup_name, value) + @cached_property + def target_field(self): + target_fields = self.get_path_info().target_fields + if len(target_fields) > 1: + raise RuntimeError("Multicolumn relations do not have a single target_field.") + return target_fields[0] + + def get_lookup(self, lookup_name): + return self.field.get_lookup(lookup_name) + def get_internal_type(self): return self.field.get_internal_type() diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 97022d554a..d54c1bc5e4 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -547,7 +547,7 @@ class SQLCompiler(object): # If we get to this point and the field is a relation to another model, # append the default ordering for that model unless the attribute name # of the field is specified. - if field.rel and path and opts.ordering and name != field.attname: + if field.is_relation and path and opts.ordering and name != field.attname: # Firstly, avoid infinite loops. if not already_seen: already_seen = set() diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 9c19e819fd..c041ef0b07 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -1038,7 +1038,7 @@ class Query(object): """ Checks the type of object passed to query relations. """ - if field.rel: + if field.is_relation: # QuerySets implement is_compatible_query_object_type() to # determine compatibility with the given field. if hasattr(value, 'is_compatible_query_object_type'): @@ -1164,16 +1164,10 @@ class Query(object): # No support for transforms for relational fields assert len(lookups) == 1 lookup_class = field.get_lookup(lookups[0]) - # Undo the changes done in setup_joins() if hasattr(final_field, 'field') branch - # This hack is needed as long as the field.rel isn't like a real field. - if field.get_path_info()[-1].target_fields != sources: - target_field = field.rel - else: - target_field = field if len(targets) == 1: - lhs = targets[0].get_col(alias, target_field) + lhs = targets[0].get_col(alias, field) else: - lhs = MultiColSource(alias, targets, sources, target_field) + lhs = MultiColSource(alias, targets, sources, field) condition = lookup_class(lhs, value) lookup_type = lookup_class.lookup_name else: @@ -1384,8 +1378,6 @@ class Query(object): reuse = can_reuse if join.m2m else None alias = self.join(connection, reuse=reuse) joins.append(alias) - if hasattr(final_field, 'field'): - final_field = final_field.field return final_field, targets, opts, joins, path def trim_joins(self, targets, joins, path):