|
| 1 | +import re |
| 2 | + |
1 | 3 | from django.core.exceptions import FullResultSet
|
2 | 4 | from django.db.models.aggregates import Aggregate
|
3 |
| -from django.db.models.expressions import CombinedExpression, Value |
| 5 | +from django.db.models.expressions import CombinedExpression, Func, Value |
4 | 6 | from django.db.models.sql.query import Query
|
5 | 7 |
|
6 | 8 |
|
@@ -74,17 +76,24 @@ def is_constant_value(value):
|
74 | 76 | if hasattr(value, "get_source_expressions"):
|
75 | 77 | # Temporary: similar limitation as above, sub-expressions should be
|
76 | 78 | # resolved in the future
|
77 |
| - simple_sub_expressions = all(map(is_constant_value, value.get_source_expressions())) |
| 79 | + constants_sub_expressions = all(map(is_constant_value, value.get_source_expressions())) |
78 | 80 | else:
|
79 |
| - simple_sub_expressions = True |
80 |
| - return ( |
81 |
| - simple_sub_expressions |
82 |
| - and isinstance(value, Value) |
83 |
| - and not ( |
84 |
| - isinstance(value, Query) |
85 |
| - or value.contains_aggregate |
86 |
| - or value.contains_over_clause |
87 |
| - or value.contains_column_references |
88 |
| - or value.contains_subquery |
89 |
| - ) |
| 81 | + constants_sub_expressions = True |
| 82 | + constants_sub_expressions = constants_sub_expressions and not ( |
| 83 | + isinstance(value, Query) |
| 84 | + or value.contains_aggregate |
| 85 | + or value.contains_over_clause |
| 86 | + or value.contains_column_references |
| 87 | + or value.contains_subquery |
| 88 | + ) |
| 89 | + return constants_sub_expressions and ( |
| 90 | + isinstance(value, Value) |
| 91 | + or |
| 92 | + # Some closed functions cannot yet be converted to constant values. |
| 93 | + # Allow Func with can_use_path as a temporary exception. |
| 94 | + (isinstance(value, Func) and value.can_use_path) |
90 | 95 | )
|
| 96 | + |
| 97 | + |
| 98 | +def valid_path_key_name(key_name): |
| 99 | + return bool(re.fullmatch(r"[A-Za-z0-9_]+", key_name)) |
0 commit comments