diff options
| author | Tim Graham <timograham@gmail.com> | 2026-03-09 16:45:50 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-09 21:45:50 +0100 |
| commit | 476e5def5fcbcf637945985a23675db0e1f59354 (patch) | |
| tree | 8decf81527e4b5fc2e75ead4c97f1d6a721d8f71 | |
| parent | 9c21dd91a3bc5d4278adfff98c7a5225947cd049 (diff) | |
Refactored PatternLookup to improve readability.
| -rw-r--r-- | django/db/models/lookups.py | 29 |
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): |
