Skip to content

Commit 476e5de

Browse files
authored
Refactored PatternLookup to improve readability.
1 parent 9c21dd9 commit 476e5de

1 file changed

Lines changed: 19 additions & 10 deletions

File tree

django/db/models/lookups.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -578,32 +578,41 @@ class PatternLookup(BuiltinLookup):
578578
prepare_rhs = False
579579

580580
def get_rhs_op(self, connection, rhs):
581-
# Assume we are in startswith. We need to produce SQL like:
582-
# col LIKE %s, ['thevalue%']
583-
# For python values we can (and should) do that directly in Python,
584-
# but if the value is for example reference to other column, then
585-
# we need to add the % pattern match to the lookup by something like
581+
# If the lookup value is a reference to another column or a transform,
582+
# then the SQL is something like:
586583
# col LIKE othercol || '%%'
587-
# So, for Python values we don't need any special pattern, but for
588-
# SQL reference values or SQL transformations we need the correct
589-
# pattern added.
590-
if hasattr(self.rhs, "as_sql") or self.bilateral_transforms:
584+
if not self.is_simple_lookup:
585+
# In that case, prepare the LIKE clause using
586+
# DatabaseWrapper.pattern_ops.
591587
pattern = connection.pattern_ops[self.lookup_name].format(
592588
connection.pattern_esc
593589
)
594590
return pattern.format(rhs)
595591
else:
592+
# Otherwise, use the LIKE in DatabaseWrapper.operators.
596593
return super().get_rhs_op(connection, rhs)
597594

598595
def process_rhs(self, qn, connection):
599596
rhs, params = super().process_rhs(qn, connection)
600-
if self.rhs_is_direct_value() and params and not self.bilateral_transforms:
597+
# Assume the lookup is startswith. For simple lookups involving a
598+
# Python value like "thevalue", the (SQL, params) is something like:
599+
# ("col LIKE %s", ['thevalue%'])
600+
if self.is_simple_lookup:
601+
# Prepare the lookup parameter, a Python value, for use in a LIKE
602+
# clause, usually by adding % signs to the beginning and/or end of
603+
# the value.
601604
param = connection.ops.prep_for_like_query(params[0])
602605
if connection.features.pattern_lookup_needs_param_pattern:
603606
param = self.param_pattern % param
604607
params = (param, *params[1:])
605608
return rhs, params
606609

610+
@property
611+
def is_simple_lookup(self):
612+
# A "simple lookup" is a Python value (as long as it's not a bilateral
613+
# transform).
614+
return self.rhs_is_direct_value() and not self.bilateral_transforms
615+
607616

608617
@Field.register_lookup
609618
class Contains(PatternLookup):

0 commit comments

Comments
 (0)