|
| 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