summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2026-03-09 16:45:50 -0400
committerGitHub <noreply@github.com>2026-03-09 21:45:50 +0100
commit476e5def5fcbcf637945985a23675db0e1f59354 (patch)
tree8decf81527e4b5fc2e75ead4c97f1d6a721d8f71
parent9c21dd91a3bc5d4278adfff98c7a5225947cd049 (diff)
Refactored PatternLookup to improve readability.
-rw-r--r--django/db/models/lookups.py29
1 files changed, 19 insertions, 10 deletions
diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py
index eaf3d69a59..4c08999fb6 100644
--- a/django/db/models/lookups.py
+++ b/django/db/models/lookups.py
@@ -578,32 +578,41 @@ class PatternLookup(BuiltinLookup):
prepare_rhs = False
def get_rhs_op(self, connection, rhs):
- # Assume we are in startswith. We need to produce SQL like:
- # col LIKE %s, ['thevalue%']
- # For python values we can (and should) do that directly in Python,
- # but if the value is for example reference to other column, then
- # we need to add the % pattern match to the lookup by something like
+ # If the lookup value is a reference to another column or a transform,
+ # then the SQL is something like:
# col LIKE othercol || '%%'
- # So, for Python values we don't need any special pattern, but for
- # SQL reference values or SQL transformations we need the correct
- # pattern added.
- if hasattr(self.rhs, "as_sql") or self.bilateral_transforms:
+ if not self.is_simple_lookup:
+ # In that case, prepare the LIKE clause using
+ # DatabaseWrapper.pattern_ops.
pattern = connection.pattern_ops[self.lookup_name].format(
connection.pattern_esc
)
return pattern.format(rhs)
else:
+ # Otherwise, use the LIKE in DatabaseWrapper.operators.
return super().get_rhs_op(connection, rhs)
def process_rhs(self, qn, connection):
rhs, params = super().process_rhs(qn, connection)
- if self.rhs_is_direct_value() and params and not self.bilateral_transforms:
+ # Assume the lookup is startswith. For simple lookups involving a
+ # Python value like "thevalue", the (SQL, params) is something like:
+ # ("col LIKE %s", ['thevalue%'])
+ if self.is_simple_lookup:
+ # Prepare the lookup parameter, a Python value, for use in a LIKE
+ # clause, usually by adding % signs to the beginning and/or end of
+ # the value.
param = connection.ops.prep_for_like_query(params[0])
if connection.features.pattern_lookup_needs_param_pattern:
param = self.param_pattern % param
params = (param, *params[1:])
return rhs, params
+ @property
+ def is_simple_lookup(self):
+ # A "simple lookup" is a Python value (as long as it's not a bilateral
+ # transform).
+ return self.rhs_is_direct_value() and not self.bilateral_transforms
+
@Field.register_lookup
class Contains(PatternLookup):