text: import time
  import datetime
  
  from flask_admin.babel import lazy_gettext
  
  from flask_admin.model import filters
  from .tools import parse_like_term
  
  
  class BasePeeweeFilter(filters.BaseFilter):
      """
          Base Peewee filter.
      """
      def __init__(self, column, name, options=None, data_type=None):
          """
              Constructor.
  
              :param column:
                  Model field
              :param name:
                  Display name
              :param options:
                  Fixed set of options
              :param data_type:
                  Client data type
          """
          super(BasePeeweeFilter, self).__init__(name, options, data_type)
  
          self.column = column
  
  
  # Common filters
  class FilterEqual(BasePeeweeFilter):
      def apply(self, query, value):
          return query.filter(self.column == value)
  
      def operation(self):
          return lazy_gettext('equals')
  
  
  class FilterNotEqual(BasePeeweeFilter):
      def apply(self, query, value):
          return query.filter(self.column != value)
  
      def operation(self):
          return lazy_gettext('not equal')
  
  
  class FilterLike(BasePeeweeFilter):
      def apply(self, query, value):
          term = parse_like_term(value)
          return query.filter(self.column ** term)
  
      def operation(self):
          return lazy_gettext('contains')
  
  
  class FilterNotLike(BasePeeweeFilter):
      def apply(self, query, value):
          term = parse_like_term(value)
          return query.filter(~(self.column ** term))
  
      def operation(self):
          return lazy_gettext('not contains')
  
  
  class FilterGreater(BasePeeweeFilter):
      def apply(self, query, value):
          return query.filter(self.column > value)
  
      def operation(self):
          return lazy_gettext('greater than')
  
  
  class FilterSmaller(BasePeeweeFilter):
      def apply(self, query, value):
          return query.filter(self.column < value)
  
      def operation(self):
          return lazy_gettext('smaller than')
  
  
  class FilterEmpty(BasePeeweeFilter, filters.BaseBooleanFilter):
      def apply(self, query, value):
          if value == '1':
              return query.filter(self.column >> None)
          else:
              return query.filter(~(self.column >> None))
  
      def operation(self):
          return lazy_gettext('empty')
  
  
  class FilterInList(BasePeeweeFilter):
      def __init__(self, column, name, options=None, data_type=None):
          super(FilterInList, self).__init__(column, name, options, data_type='select2-tags')
  
      def clean(self, value):
          return [v.strip() for v in value.split(',') if v.strip()]
  
      def apply(self, query, value):
          return query.filter(self.column << value)
  
      def operation(self):
          return lazy_gettext('in list')
  
  
  class FilterNotInList(FilterInList):
      def apply(self, query, value):
          # NOT IN can exclude NULL values, so "or_ == None" needed to be added
          return query.filter(~(self.column << value) | (self.column >> None))
  
      def operation(self):
          return lazy_gettext('not in list')
  
  
  # Customized type filters
  class BooleanEqualFilter(FilterEqual, filters.BaseBooleanFilter):
      pass
  
  
  class BooleanNotEqualFilter(FilterNotEqual, filters.BaseBooleanFilter):
      pass
  
  
  class IntEqualFilter(FilterEqual, filters.BaseIntFilter):
      pass
  
  
  class IntNotEqualFilter(FilterNotEqual, filters.BaseIntFilter):
      pass
  
  
  class IntGreaterFilter(FilterGreater, filters.BaseIntFilter):
      pass
  
  
  class IntSmallerFilter(FilterSmaller, filters.BaseIntFilter):
      pass
  
  
  class IntInListFilter(filters.BaseIntListFilter, FilterInList):
      pass
  
  
  class IntNotInListFilter(filters.BaseIntListFilter, FilterNotInList):
      pass
  
  
  class FloatEqualFilter(FilterEqual, filters.BaseFloatFilter):
      pass
  
  
  class FloatNotEqualFilter(FilterNotEqual, filters.BaseFloatFilter):
      pass
  
  
  class FloatGreaterFilter(FilterGreater, filters.BaseFloatFilter):
      pass
  
  
  class FloatSmallerFilter(FilterSmaller, filters.BaseFloatFilter):
      pass
  
  
  class FloatInListFilter(filters.BaseFloatListFilter, FilterInList):
      pass
  
  
  class FloatNotInListFilter(filters.BaseFloatListFilter, FilterNotInList):
      pass
  
  
  class DateEqualFilter(FilterEqual, filters.BaseDateFilter):
      pass
  
  
  class DateNotEqualFilter(FilterNotEqual, filters.BaseDateFilter):
      pass
  
  
  class DateGreaterFilter(FilterGreater, filters.BaseDateFilter):
      pass
  
  
  class DateSmallerFilter(FilterSmaller, filters.BaseDateFilter):
      pass
  
  
  class DateBetweenFilter(BasePeeweeFilter, filters.BaseDateBetweenFilter):
      def __init__(self, column, name, options=None, data_type=None):
          super(DateBetweenFilter, self).__init__(column,
                                                  name,
                                                  options,
                                                  data_type='daterangepicker')
  
      def apply(self, query, value):
          start, end = value
          return query.filter(self.column.between(start, end))
  
  
  class DateNotBetweenFilter(DateBetweenFilter):
      def apply(self, query, value):
          start, end = value
          return query.filter(~(self.column.between(start, end)))
  
      def operation(self):
          return lazy_gettext('not between')
  
  
  class DateTimeEqualFilter(FilterEqual, filters.BaseDateTimeFilter):
      pass
  
  
  class DateTimeNotEqualFilter(FilterNotEqual, filters.BaseDateTimeFilter):
      pass
  
  
  class DateTimeGreaterFilter(FilterGreater, filters.BaseDateTimeFilter):
      pass
  
  
  class DateTimeSmallerFilter(FilterSmaller, filters.BaseDateTimeFilter):
      pass
  
  
  class DateTimeBetweenFilter(BasePeeweeFilter, filters.BaseDateTimeBetweenFilter):
      def __init__(self, column, name, options=None, data_type=None):
          super(DateTimeBetweenFilter, self).__init__(column,
                                                      name,
                                                      options,
                                                      data_type='datetimerangepicker')
  
      def apply(self, query, value):
          start, end = value
          return query.filter(self.column.between(start, end))
  
  
  class DateTimeNotBetweenFilter(DateTimeBetweenFilter):
      def apply(self, query, value):
          start, end = value
          return query.filter(~(self.column.between(start, end)))
  
      def operation(self):
          return lazy_gettext('not between')
  
  
  class TimeEqualFilter(FilterEqual, filters.BaseTimeFilter):
      pass
  
  
  class TimeNotEqualFilter(FilterNotEqual, filters.BaseTimeFilter):
      pass
  
  
  class TimeGreaterFilter(FilterGreater, filters.BaseTimeFilter):
      pass
  
  
  class TimeSmallerFilter(FilterSmaller, filters.BaseTimeFilter):
      pass
  
  
  class TimeBetweenFilter(BasePeeweeFilter, filters.BaseTimeBetweenFilter):
      def __init__(self, column, name, options=None, data_type=None):
          super(TimeBetweenFilter, self).__init__(column,
                                                  name,
                                                  options,
                                                  data_type='timerangepicker')
  
      def apply(self, query, value):
          start, end = value
          return query.filter(self.column.between(start, end))
  
  
  class TimeNotBetweenFilter(TimeBetweenFilter):
      def apply(self, query, value):
          start, end = value
          return query.filter(~(self.column.between(start, end)))
  
      def operation(self):
          return lazy_gettext('not between')
  
  
  # Base peewee filter field converter
  class FilterConverter(filters.BaseFilterConverter):
      strings = (FilterEqual, FilterNotEqual, FilterLike, FilterNotLike,
                 FilterEmpty, FilterInList, FilterNotInList)
      int_filters = (IntEqualFilter, IntNotEqualFilter, IntGreaterFilter,
                     IntSmallerFilter, FilterEmpty, IntInListFilter,
                     IntNotInListFilter)
      float_filters = (FloatEqualFilter, FloatNotEqualFilter, FloatGreaterFilter,
                       FloatSmallerFilter, FilterEmpty, FloatInListFilter,
                       FloatNotInListFilter)
      bool_filters = (BooleanEqualFilter, BooleanNotEqualFilter)
      date_filters = (DateEqualFilter, DateNotEqualFilter, DateGreaterFilter,
                      DateSmallerFilter, DateBetweenFilter, DateNotBetweenFilter,
                      FilterEmpty)
      datetime_filters = (DateTimeEqualFilter, DateTimeNotEqualFilter,
                          DateTimeGreaterFilter, DateTimeSmallerFilter,
                          DateTimeBetweenFilter, DateTimeNotBetweenFilter,
                          FilterEmpty)
      time_filters = (TimeEqualFilter, TimeNotEqualFilter, TimeGreaterFilter,
                      TimeSmallerFilter, TimeBetweenFilter, TimeNotBetweenFilter,
                      FilterEmpty)
  
      def convert(self, type_name, column, name):
          filter_name = type_name.lower()
  
          if filter_name in self.converters:
              return self.converters[filter_name](column, name)
  
          return None
  
      @filters.convert('CharField', 'TextField')
      def conv_string(self, column, name):
          return [f(column, name) for f in self.strings]
  
      @filters.convert('BooleanField')
      def conv_bool(self, column, name):
          return [f(column, name) for f in self.bool_filters]
  
      @filters.convert('IntegerField', 'BigIntegerField')
      def conv_int(self, column, name):
          return [f(column, name) for f in self.int_filters]
  
      @filters.convert('DecimalField', 'FloatField', 'DoubleField')
      def conv_float(self, column, name):
          return [f(column, name) for f in self.float_filters]
  
      @filters.convert('DateField')
      def conv_date(self, column, name):
          return [f(column, name) for f in self.date_filters]
  
      @filters.convert('DateTimeField')
      def conv_datetime(self, column, name):
          return [f(column, name) for f in self.datetime_filters]
  
      @filters.convert('TimeField')
      def conv_time(self, column, name):
          return [f(column, name) for f in self.time_filters]
  