summaryrefslogtreecommitdiff
path: root/django/db/models/sql
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2020-04-05 15:45:06 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-04-06 10:19:49 +0200
commit513948735b799239f3ef8c89397592445e1a0cd5 (patch)
tree8209114fe5dcd254318c86781bcce54c95d98d80 /django/db/models/sql
parent98ea4f0f4696221f00e111f1d623452002192e6c (diff)
Fixed #31426 -- Added proper field validation to QuerySet.order_by().
Resolve the field reference instead of using fragile regex based string reference validation.
Diffstat (limited to 'django/db/models/sql')
-rw-r--r--django/db/models/sql/constants.py3
-rw-r--r--django/db/models/sql/query.py18
2 files changed, 14 insertions, 7 deletions
diff --git a/django/db/models/sql/constants.py b/django/db/models/sql/constants.py
index 1ff44252c5..a1db61b9ff 100644
--- a/django/db/models/sql/constants.py
+++ b/django/db/models/sql/constants.py
@@ -2,8 +2,6 @@
Constants specific to the SQL storage portion of the ORM.
"""
-from django.utils.regex_helper import _lazy_re_compile
-
# Size of each "chunk" for get_iterator calls.
# Larger values are slightly faster at the expense of more storage space.
GET_ITERATOR_CHUNK_SIZE = 100
@@ -16,7 +14,6 @@ SINGLE = 'single'
CURSOR = 'cursor'
NO_RESULTS = 'no results'
-ORDER_PATTERN = _lazy_re_compile(r'\?|[-+]?[.\w]+$')
ORDER_DIR = {
'ASC': ('ASC', 'DESC'),
'DESC': ('DESC', 'ASC'),
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 82ff6bf4ea..bb230647eb 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -30,9 +30,7 @@ from django.db.models.lookups import Lookup
from django.db.models.query_utils import (
Q, check_rel_lookup_compatibility, refs_expression,
)
-from django.db.models.sql.constants import (
- INNER, LOUTER, ORDER_DIR, ORDER_PATTERN, SINGLE,
-)
+from django.db.models.sql.constants import INNER, LOUTER, ORDER_DIR, SINGLE
from django.db.models.sql.datastructures import (
BaseTable, Empty, Join, MultiJoin,
)
@@ -1895,7 +1893,7 @@ class Query(BaseExpression):
"""
errors = []
for item in ordering:
- if isinstance(item, str) and ORDER_PATTERN.match(item):
+ if isinstance(item, str):
if '.' in item:
warnings.warn(
'Passing column raw column aliases to order_by() is '
@@ -1904,6 +1902,18 @@ class Query(BaseExpression):
category=RemovedInDjango40Warning,
stacklevel=3,
)
+ continue
+ if item == '?':
+ continue
+ if item.startswith('-'):
+ item = item[1:]
+ if item in self.annotations:
+ continue
+ if self.extra and item in self.extra:
+ continue
+ # names_to_path() validates the lookup. A descriptive
+ # FieldError will be raise if it's not.
+ self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
elif not hasattr(item, 'resolve_expression'):
errors.append(item)
if getattr(item, 'contains_aggregate', False):