Add support for integer search filters.
This mostly just avoids to suppress type errors by stripping out non-numeric chars from input.
This commit is contained in:
parent
9f62ed6b07
commit
7bbadfd338
|
@ -26,6 +26,8 @@ Grid Search Filters
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
from sqlalchemy import func, or_
|
from sqlalchemy import func, or_
|
||||||
|
|
||||||
from webhelpers.html import tags
|
from webhelpers.html import tags
|
||||||
|
@ -181,6 +183,23 @@ def filter_ilike(field):
|
||||||
return {'lk': ilike, 'nl': not_ilike}
|
return {'lk': ilike, 'nl': not_ilike}
|
||||||
|
|
||||||
|
|
||||||
|
def filter_int(field):
|
||||||
|
"""
|
||||||
|
Returns a filter map entry for an integer field. This provides exact
|
||||||
|
matching but also strips out non-numeric characters to avoid type errors.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def filter_is(q, v):
|
||||||
|
v = re.sub(r'\D', '', v or '')
|
||||||
|
return q.filter(field == int(v)) if v else q
|
||||||
|
|
||||||
|
def filter_nt(q, v):
|
||||||
|
v = re.sub(r'\D', '', v or '')
|
||||||
|
return q.filter(field != int(v)) if v else q
|
||||||
|
|
||||||
|
return {'is': filter_is, 'nt': filter_nt}
|
||||||
|
|
||||||
|
|
||||||
def filter_soundex(field):
|
def filter_soundex(field):
|
||||||
"""
|
"""
|
||||||
Returns a filter map entry which leverages the `soundex()` SQL function.
|
Returns a filter map entry which leverages the `soundex()` SQL function.
|
||||||
|
@ -256,7 +275,7 @@ def get_filter_config(prefix, request, filter_map, **kwargs):
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
def get_filter_map(cls, exact=[], ilike=[], **kwargs):
|
def get_filter_map(cls, exact=[], ilike=[], int_=[], **kwargs):
|
||||||
"""
|
"""
|
||||||
Convenience function which returns a "filter map" for ``cls``.
|
Convenience function which returns a "filter map" for ``cls``.
|
||||||
|
|
||||||
|
@ -266,6 +285,9 @@ def get_filter_map(cls, exact=[], ilike=[], **kwargs):
|
||||||
``ilike``, if provided, should be a list of field names for which "ILIKE"
|
``ilike``, if provided, should be a list of field names for which "ILIKE"
|
||||||
filtering is to be allowed.
|
filtering is to be allowed.
|
||||||
|
|
||||||
|
``int_``, if provided, should be a list of field names for which "integer"
|
||||||
|
filtering is to be allowed.
|
||||||
|
|
||||||
Any remaining ``kwargs`` are assumed to be filter map entries themselves,
|
Any remaining ``kwargs`` are assumed to be filter map entries themselves,
|
||||||
and are added directly to the map.
|
and are added directly to the map.
|
||||||
"""
|
"""
|
||||||
|
@ -275,6 +297,8 @@ def get_filter_map(cls, exact=[], ilike=[], **kwargs):
|
||||||
fmap[name] = filter_exact(getattr(cls, name))
|
fmap[name] = filter_exact(getattr(cls, name))
|
||||||
for name in ilike:
|
for name in ilike:
|
||||||
fmap[name] = filter_ilike(getattr(cls, name))
|
fmap[name] = filter_ilike(getattr(cls, name))
|
||||||
|
for name in int_:
|
||||||
|
fmap[name] = filter_int(getattr(cls, name))
|
||||||
fmap.update(kwargs)
|
fmap.update(kwargs)
|
||||||
return fmap
|
return fmap
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,9 @@ class SearchableAlchemyGridView(PagedAlchemyGridView):
|
||||||
def filter_ilike(self, field):
|
def filter_ilike(self, field):
|
||||||
return grids.search.filter_ilike(field)
|
return grids.search.filter_ilike(field)
|
||||||
|
|
||||||
|
def filter_int(self, field):
|
||||||
|
return grids.search.filter_int(field)
|
||||||
|
|
||||||
def filter_soundex(self, field):
|
def filter_soundex(self, field):
|
||||||
return grids.search.filter_soundex(field)
|
return grids.search.filter_soundex(field)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue