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:
Lance Edgar 2015-01-13 21:22:56 -06:00
parent 9f62ed6b07
commit 7bbadfd338
2 changed files with 28 additions and 1 deletions

View file

@ -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

View file

@ -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)