diff --git a/src/wuttaweb/grids/base.py b/src/wuttaweb/grids/base.py index e01c5e1..ba402ce 100644 --- a/src/wuttaweb/grids/base.py +++ b/src/wuttaweb/grids/base.py @@ -1976,6 +1976,7 @@ class Grid: for filtr in self.filters.values(): filters.append({ 'key': filtr.key, + 'data_type': filtr.data_type, 'active': filtr.active, 'visible': filtr.active, 'verbs': filtr.get_verbs(), diff --git a/src/wuttaweb/grids/filters.py b/src/wuttaweb/grids/filters.py index 1cbdb89..6be29c7 100644 --- a/src/wuttaweb/grids/filters.py +++ b/src/wuttaweb/grids/filters.py @@ -24,6 +24,7 @@ Grid Filters """ +import datetime import logging import sqlalchemy as sa @@ -69,6 +70,18 @@ class GridFilter: Display label for the filter field. + .. attribute:: data_type + + Simplistic "data type" which the filter supports. So far this + will be one of: + + * ``'string'`` + * ``'date'`` + + Note that this mainly applies to the "value input" used by the + filter. There is no data type for boolean since it does not + need a value input; the verb is enough. + .. attribute:: active Boolean indicating whether the filter is currently active. @@ -110,12 +123,18 @@ class GridFilter: See also :attr:`default_verb`. """ + data_type = 'string' default_verbs = ['equal', 'not_equal'] default_verb_labels = { 'is_any': "is any", 'equal': "equal to", 'not_equal': "not equal to", + 'greater_than': "greater than", + 'greater_equal': "greater than or equal to", + 'less_than': "less than", + 'less_equal': "less than or equal to", + # 'between': "between", 'is_true': "is true", 'is_false': "is false", 'is_false_null': "is false or null", @@ -343,6 +362,42 @@ class AlchemyFilter(GridFilter): self.model_property != value, )) + def filter_greater_than(self, query, value): + """ + Filter data with a greater than (``>``) condition. + """ + value = self.coerce_value(value) + if value is None: + return query + return query.filter(self.model_property > value) + + def filter_greater_equal(self, query, value): + """ + Filter data with a greater than or equal (``>=``) condition. + """ + value = self.coerce_value(value) + if value is None: + return query + return query.filter(self.model_property >= value) + + def filter_less_than(self, query, value): + """ + Filter data with a less than (``<``) condition. + """ + value = self.coerce_value(value) + if value is None: + return query + return query.filter(self.model_property < value) + + def filter_less_equal(self, query, value): + """ + Filter data with a less than or equal (``<=``) condition. + """ + value = self.coerce_value(value) + if value is None: + return query + return query.filter(self.model_property <= value) + def filter_is_null(self, query, value): """ Filter data with an ``IS NULL`` query. The value is ignored. @@ -467,9 +522,52 @@ class BooleanAlchemyFilter(AlchemyFilter): self.model_property == None)) +class DateAlchemyFilter(AlchemyFilter): + """ + SQLAlchemy filter option for a + :class:`sqlalchemy:sqlalchemy.types.Date` column. + + Subclass of :class:`AlchemyFilter`. + """ + data_type = 'date' + default_verbs = [ + 'equal', + 'not_equal', + 'greater_than', + 'greater_equal', + 'less_than', + 'less_equal', + # 'between', + ] + + default_verb_labels = { + 'equal': "on", + 'not_equal': "not on", + 'greater_than': "after", + 'greater_equal': "on or after", + 'less_than': "before", + 'less_equal': "on or before", + # 'between': "between", + } + + def coerce_value(self, value): + """ """ + if value: + if isinstance(value, datetime.date): + return value + + try: + dt = datetime.datetime.strptime(value, '%Y-%m-%d') + except ValueError: + log.warning("invalid date value: %s", value) + else: + return dt.date() + + default_sqlalchemy_filters = { None: AlchemyFilter, sa.String: StringAlchemyFilter, sa.Text: StringAlchemyFilter, sa.Boolean: BooleanAlchemyFilter, + sa.Date: DateAlchemyFilter, } diff --git a/src/wuttaweb/templates/wutta-components.mako b/src/wuttaweb/templates/wutta-components.mako index 5664933..2a18ea7 100644 --- a/src/wuttaweb/templates/wutta-components.mako +++ b/src/wuttaweb/templates/wutta-components.mako @@ -6,6 +6,7 @@ ${self.make_wutta_timepicker_component()} ${self.make_wutta_filter_component()} ${self.make_wutta_filter_value_component()} + ${self.make_wutta_filter_date_value_component()} ${self.make_wutta_tool_panel_component()} @@ -155,11 +156,14 @@ <%def name="make_wutta_datepicker_component()"> +<%def name="make_wutta_filter_date_value_component()"> + + + + <%def name="make_wutta_tool_panel_component()">