Escape underscore char for "contains" query filter
since underscore has special meaning for LIKE clause
This commit is contained in:
parent
666c16b74e
commit
d0d568b3a5
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -484,9 +484,13 @@ class AlchemyStringFilter(AlchemyGridFilter):
|
|||
"""
|
||||
if value is None or value == '':
|
||||
return query
|
||||
return query.filter(sa.and_(
|
||||
*[self.column.ilike(self.encode_value('%{}%'.format(v)))
|
||||
for v in value.split()]))
|
||||
|
||||
criteria = []
|
||||
for val in value.split():
|
||||
val = val.replace('_', r'\_')
|
||||
val = self.encode_value(f'%{val}%')
|
||||
criteria.append(self.column.ilike(val))
|
||||
return query.filter(sa.and_(*criteria))
|
||||
|
||||
def filter_does_not_contain(self, query, value):
|
||||
"""
|
||||
|
@ -495,14 +499,17 @@ class AlchemyStringFilter(AlchemyGridFilter):
|
|||
if value is None or value == '':
|
||||
return query
|
||||
|
||||
criteria = []
|
||||
for val in value.split():
|
||||
val = val.replace('_', r'\_')
|
||||
val = self.encode_value(f'%{val}%')
|
||||
criteria.append(~self.column.ilike(val))
|
||||
|
||||
# When saying something is 'not like' something else, we must also
|
||||
# include things which are nothing at all, in our result set.
|
||||
return query.filter(sa.or_(
|
||||
self.column == None,
|
||||
sa.and_(
|
||||
*[~self.column.ilike(self.encode_value('%{}%'.format(v)))
|
||||
for v in value.split()]),
|
||||
))
|
||||
sa.and_(*criteria)))
|
||||
|
||||
def filter_contains_any_of(self, query, value):
|
||||
"""
|
||||
|
@ -531,9 +538,12 @@ class AlchemyStringFilter(AlchemyGridFilter):
|
|||
|
||||
conditions = []
|
||||
for value in values:
|
||||
conditions.append(sa.and_(
|
||||
*[self.column.ilike(self.encode_value('%{}%'.format(v)))
|
||||
for v in value.split()]))
|
||||
criteria = []
|
||||
for val in value.split():
|
||||
val = val.replace('_', r'\_')
|
||||
val = self.encode_value(f'%{val}%')
|
||||
criteria.append(self.column.ilike(val))
|
||||
conditions.append(sa.and_(*criteria))
|
||||
|
||||
return query.filter(sa.or_(*conditions))
|
||||
|
||||
|
@ -588,8 +598,13 @@ class AlchemyByteStringFilter(AlchemyStringFilter):
|
|||
"""
|
||||
if value is None or value == '':
|
||||
return query
|
||||
return query.filter(sa.and_(
|
||||
*[self.column.ilike(b'%{}%'.format(v)) for v in value.split()]))
|
||||
|
||||
criteria = []
|
||||
for val in value.split():
|
||||
val = val.replace('_', r'\_')
|
||||
val = b'%{}%'.format(val)
|
||||
criteria.append(self.column.ilike(val))
|
||||
return query.filters(sa.and_(*criteria))
|
||||
|
||||
def filter_does_not_contain(self, query, value):
|
||||
"""
|
||||
|
@ -598,13 +613,16 @@ class AlchemyByteStringFilter(AlchemyStringFilter):
|
|||
if value is None or value == '':
|
||||
return query
|
||||
|
||||
for val in value.split():
|
||||
val = val.replace('_', '\_')
|
||||
val = b'%{}%'.format(val)
|
||||
criteria.append(~self.column.ilike(val))
|
||||
|
||||
# When saying something is 'not like' something else, we must also
|
||||
# include things which are nothing at all, in our result set.
|
||||
return query.filter(sa.or_(
|
||||
self.column == None,
|
||||
sa.and_(
|
||||
*[~self.column.ilike(b'%{}%'.format(v)) for v in value.split()]),
|
||||
))
|
||||
sa.and_(*criteria)))
|
||||
|
||||
|
||||
class AlchemyNumericFilter(AlchemyGridFilter):
|
||||
|
|
Loading…
Reference in a new issue