summaryrefslogtreecommitdiff
path: root/django/db/models/sql/compiler.py
diff options
context:
space:
mode:
authorMatthew Wilkes <git@matthewwilkes.name>2017-06-18 16:53:40 +0100
committerTim Graham <timograham@gmail.com>2018-02-10 19:08:55 -0500
commit2162f0983de0dfe2178531638ce7ea56f54dd4e7 (patch)
treebb1e859159200fa7ebeeaa02ec3908e1cf5d2655 /django/db/models/sql/compiler.py
parentbf26f66029bca94b007a2452679ac004598364a6 (diff)
Fixed #24747 -- Allowed transforms in QuerySet.order_by() and distinct(*fields).
Diffstat (limited to 'django/db/models/sql/compiler.py')
-rw-r--r--django/db/models/sql/compiler.py33
1 files changed, 19 insertions, 14 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 1f78a8b5b2..1fdbd156b6 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -451,7 +451,7 @@ class SQLCompiler:
raise NotSupportedError('{} is not supported on this database backend.'.format(combinator))
result, params = self.get_combinator_sql(combinator, self.query.combinator_all)
else:
- distinct_fields = self.get_distinct()
+ distinct_fields, distinct_params = self.get_distinct()
# This must come after 'select', 'ordering', and 'distinct'
# (see docstring of get_from_clause() for details).
from_, f_params = self.get_from_clause()
@@ -461,7 +461,12 @@ class SQLCompiler:
params = []
if self.query.distinct:
- result.append(self.connection.ops.distinct_sql(distinct_fields))
+ distinct_result, distinct_params = self.connection.ops.distinct_sql(
+ distinct_fields,
+ distinct_params,
+ )
+ result += distinct_result
+ params += distinct_params
out_cols = []
col_idx = 1
@@ -621,21 +626,22 @@ class SQLCompiler:
This method can alter the tables in the query, and thus it must be
called before get_from_clause().
"""
- qn = self.quote_name_unless_alias
- qn2 = self.connection.ops.quote_name
result = []
+ params = []
opts = self.query.get_meta()
for name in self.query.distinct_fields:
parts = name.split(LOOKUP_SEP)
- _, targets, alias, joins, path, _ = self._setup_joins(parts, opts, None)
+ _, targets, alias, joins, path, _, transform_function = self._setup_joins(parts, opts, None)
targets, alias, _ = self.query.trim_joins(targets, joins, path)
for target in targets:
if name in self.query.annotation_select:
result.append(name)
else:
- result.append("%s.%s" % (qn(alias), qn2(target.column)))
- return result
+ r, p = self.compile(transform_function(target, alias))
+ result.append(r)
+ params.append(p)
+ return result, params
def find_ordering_name(self, name, opts, alias=None, default_order='ASC',
already_seen=None):
@@ -647,7 +653,7 @@ class SQLCompiler:
name, order = get_order_dir(name, default_order)
descending = order == 'DESC'
pieces = name.split(LOOKUP_SEP)
- field, targets, alias, joins, path, opts = self._setup_joins(pieces, opts, alias)
+ field, targets, alias, joins, path, opts, transform_function = self._setup_joins(pieces, opts, alias)
# 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
@@ -666,7 +672,7 @@ class SQLCompiler:
order, already_seen))
return results
targets, alias, _ = self.query.trim_joins(targets, joins, path)
- return [(OrderBy(t.get_col(alias), descending=descending), False) for t in targets]
+ return [(OrderBy(transform_function(t, alias), descending=descending), False) for t in targets]
def _setup_joins(self, pieces, opts, alias):
"""
@@ -677,10 +683,9 @@ class SQLCompiler:
match. Executing SQL where this is not true is an error.
"""
alias = alias or self.query.get_initial_alias()
- field, targets, opts, joins, path = self.query.setup_joins(
- pieces, opts, alias)
+ field, targets, opts, joins, path, transform_function = self.query.setup_joins(pieces, opts, alias)
alias = joins[-1]
- return field, targets, alias, joins, path, opts
+ return field, targets, alias, joins, path, opts, transform_function
def get_from_clause(self):
"""
@@ -786,7 +791,7 @@ class SQLCompiler:
}
related_klass_infos.append(klass_info)
select_fields = []
- _, _, _, joins, _ = self.query.setup_joins(
+ _, _, _, joins, _, _ = self.query.setup_joins(
[f.name], opts, root_alias)
alias = joins[-1]
columns = self.get_default_columns(start_alias=alias, opts=f.remote_field.model._meta)
@@ -843,7 +848,7 @@ class SQLCompiler:
break
if name in self.query._filtered_relations:
fields_found.add(name)
- f, _, join_opts, joins, _ = self.query.setup_joins([name], opts, root_alias)
+ f, _, join_opts, joins, _, _ = self.query.setup_joins([name], opts, root_alias)
model = join_opts.model
alias = joins[-1]
from_parent = issubclass(model, opts.model) and model is not opts.model