Commit 5e46f3fa authored by Paul Brown's avatar Paul Brown

fix mongoengine and peewee exceptions when filtering for noninteger values

parent 0eff8c1e
......@@ -134,6 +134,54 @@ class BooleanNotEqualFilter(FilterNotEqual, filters.BaseBooleanFilter):
return query.filter(**flt)
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(FilterInList, filters.BaseIntListFilter):
pass
class IntNotInListFilter(FilterNotInList, filters.BaseIntListFilter):
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(FilterInList, filters.BaseFloatListFilter):
pass
class FloatNotInListFilter(FilterNotInList, filters.BaseFloatListFilter):
pass
class DateTimeEqualFilter(FilterEqual, filters.BaseDateTimeFilter):
pass
......@@ -150,31 +198,18 @@ class DateTimeSmallerFilter(FilterSmaller, filters.BaseDateTimeFilter):
pass
class DateTimeBetweenFilter(BaseMongoEngineFilter):
class DateTimeBetweenFilter(BaseMongoEngineFilter, filters.BaseDateTimeBetweenFilter):
def __init__(self, column, name, options=None, data_type=None):
super(DateTimeBetweenFilter, self).__init__(column, name, options, data_type='datetimerangepicker')
def clean(self, value):
return [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S') for range in value.split(' to ')]
super(DateTimeBetweenFilter, self).__init__(column,
name,
options,
data_type='datetimerangepicker')
def apply(self, query, value):
start, end = value
flt = {'%s__gte' % self.column.name: start, '%s__lte' % self.column.name: end}
return query.filter(**flt)
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
value = [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S') for range in value.split(' to ')]
if (len(value) == 2) and (value[0] <= value[1]):
return True
else:
return False
except ValueError:
return False
class DateTimeNotBetweenFilter(DateTimeBetweenFilter):
def apply(self, query, value):
......@@ -188,11 +223,18 @@ class DateTimeNotBetweenFilter(DateTimeBetweenFilter):
# Base peewee filter field converter
class FilterConverter(filters.BaseFilterConverter):
strings = (FilterEqual, FilterNotEqual, FilterLike, FilterNotLike, FilterEmpty, FilterInList, FilterNotInList)
numeric = (FilterEqual, FilterNotEqual, FilterGreater, FilterSmaller, FilterEmpty, FilterInList, FilterNotInList)
bool = (BooleanEqualFilter, BooleanNotEqualFilter)
datetime_filters = (DateTimeEqualFilter, DateTimeNotEqualFilter, DateTimeGreaterFilter,
DateTimeSmallerFilter, DateTimeBetweenFilter, DateTimeNotBetweenFilter,
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)
datetime_filters = (DateTimeEqualFilter, DateTimeNotEqualFilter,
DateTimeGreaterFilter, DateTimeSmallerFilter,
DateTimeBetweenFilter, DateTimeNotBetweenFilter,
FilterEmpty)
def convert(self, type_name, column, name):
......@@ -207,11 +249,15 @@ class FilterConverter(filters.BaseFilterConverter):
@filters.convert('BooleanField')
def conv_bool(self, column, name):
return [f(column, name) for f in self.bool]
return [f(column, name) for f in self.bool_filters]
@filters.convert('IntField', 'DecimalField', 'FloatField', 'LongField')
@filters.convert('IntField', 'LongField')
def conv_int(self, column, name):
return [f(column, name) for f in self.numeric]
return [f(column, name) for f in self.int_filters]
@filters.convert('DecimalField', 'FloatField')
def conv_float(self, column, name):
return [f(column, name) for f in self.float_filters]
@filters.convert('DateTimeField', 'ComplexDateTimeField')
def conv_datetime(self, column, name):
......
......@@ -123,6 +123,54 @@ 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(FilterInList, filters.BaseIntListFilter):
pass
class IntNotInListFilter(FilterNotInList, filters.BaseIntListFilter):
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(FilterInList, filters.BaseFloatListFilter):
pass
class FloatNotInListFilter(FilterNotInList, filters.BaseFloatListFilter):
pass
class DateEqualFilter(FilterEqual, filters.BaseDateFilter):
pass
......@@ -139,32 +187,17 @@ class DateSmallerFilter(FilterSmaller, filters.BaseDateFilter):
pass
class DateBetweenFilter(BasePeeweeFilter):
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 clean(self, value):
return [datetime.datetime.strptime(range, '%Y-%m-%d') for range in value.split(' to ')]
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))
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
value = [datetime.datetime.strptime(range, '%Y-%m-%d') for range in value.split(' to ')]
# if " to " is missing, fail validation
# if end date is before start date, fail validation
if (len(value) == 2) and (value[0] <= value[1]):
return True
else:
return False
except ValueError:
return False
class DateNotBetweenFilter(DateBetweenFilter):
def apply(self, query, value):
......@@ -191,30 +224,17 @@ class DateTimeSmallerFilter(FilterSmaller, filters.BaseDateTimeFilter):
pass
class DateTimeBetweenFilter(BasePeeweeFilter):
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 clean(self, value):
return [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S') for range in value.split(' to ')]
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))
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
value = [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S') for range in value.split(' to ')]
if (len(value) == 2) and (value[0] <= value[1]):
return True
else:
return False
except ValueError:
return False
class DateTimeNotBetweenFilter(DateTimeBetweenFilter):
def apply(self, query, value):
......@@ -241,37 +261,17 @@ class TimeSmallerFilter(FilterSmaller, filters.BaseTimeFilter):
pass
class TimeBetweenFilter(BasePeeweeFilter):
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 clean(self, value):
timetuples = [time.strptime(range, '%H:%M:%S')
for range in value.split(' to ')]
return [datetime.time(timetuple.tm_hour,
timetuple.tm_min,
timetuple.tm_sec)
for timetuple in timetuples]
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))
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
timetuples = [time.strptime(range, '%H:%M:%S')
for range in value.split(' to ')]
if (len(timetuples) == 2) and (timetuples[0] <= timetuples[1]):
return True
else:
return False
except ValueError:
raise
return False
class TimeNotBetweenFilter(TimeBetweenFilter):
def apply(self, query, value):
......@@ -284,16 +284,25 @@ class TimeNotBetweenFilter(TimeBetweenFilter):
# Base peewee filter field converter
class FilterConverter(filters.BaseFilterConverter):
strings = (FilterEqual, FilterNotEqual, FilterLike, FilterNotLike, FilterEmpty, FilterInList, FilterNotInList)
numeric = (FilterEqual, FilterNotEqual, FilterGreater, FilterSmaller, FilterEmpty, FilterInList, FilterNotInList)
bool = (BooleanEqualFilter, BooleanNotEqualFilter)
date_filters = (DateEqualFilter, DateNotEqualFilter, DateGreaterFilter, DateSmallerFilter,
DateBetweenFilter, DateNotBetweenFilter, FilterEmpty)
datetime_filters = (DateTimeEqualFilter, DateTimeNotEqualFilter, DateTimeGreaterFilter,
DateTimeSmallerFilter, DateTimeBetweenFilter, DateTimeNotBetweenFilter,
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)
time_filters = (TimeEqualFilter, TimeNotEqualFilter, TimeGreaterFilter, TimeSmallerFilter,
TimeBetweenFilter, TimeNotBetweenFilter, FilterEmpty)
def convert(self, type_name, column, name):
if type_name in self.converters:
......@@ -307,12 +316,15 @@ class FilterConverter(filters.BaseFilterConverter):
@filters.convert('BooleanField')
def conv_bool(self, column, name):
return [f(column, name) for f in self.bool]
return [f(column, name) for f in self.bool_filters]
@filters.convert('IntegerField', 'DecimalField', 'FloatField',
'DoubleField', 'BigIntegerField')
@filters.convert('IntegerField', 'BigIntegerField')
def conv_int(self, column, name):
return [f(column, name) for f in self.numeric]
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):
......
......@@ -123,6 +123,54 @@ 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(FilterInList, filters.BaseIntListFilter):
pass
class IntNotInListFilter(FilterNotInList, filters.BaseIntListFilter):
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(FilterInList, filters.BaseFloatListFilter):
pass
class FloatNotInListFilter(FilterNotInList, filters.BaseFloatListFilter):
pass
class DateEqualFilter(FilterEqual, filters.BaseDateFilter):
pass
......@@ -139,32 +187,17 @@ class DateSmallerFilter(FilterSmaller, filters.BaseDateFilter):
pass
class DateBetweenFilter(BaseSQLAFilter):
class DateBetweenFilter(BaseSQLAFilter, filters.BaseDateBetweenFilter):
def __init__(self, column, name, options=None, data_type=None):
super(DateBetweenFilter, self).__init__(column, name, options, data_type='daterangepicker')
def clean(self, value):
return [datetime.datetime.strptime(range, '%Y-%m-%d') for range in value.split(' to ')]
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))
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
value = [datetime.datetime.strptime(range, '%Y-%m-%d') for range in value.split(' to ')]
# if " to " is missing, fail validation
# sqlalchemy's .between() will not work if end date is before start date
if (len(value) == 2) and (value[0] <= value[1]):
return True
else:
return False
except ValueError:
return False
class DateNotBetweenFilter(DateBetweenFilter):
def apply(self, query, value):
......@@ -192,30 +225,17 @@ class DateTimeSmallerFilter(FilterSmaller, filters.BaseDateTimeFilter):
pass
class DateTimeBetweenFilter(BaseSQLAFilter):
class DateTimeBetweenFilter(BaseSQLAFilter, filters.BaseDateTimeBetweenFilter):
def __init__(self, column, name, options=None, data_type=None):
super(DateTimeBetweenFilter, self).__init__(column, name, options, data_type='datetimerangepicker')
def clean(self, value):
return [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S') for range in value.split(' to ')]
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))
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
value = [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S') for range in value.split(' to ')]
if (len(value) == 2) and (value[0] <= value[1]):
return True
else:
return False
except ValueError:
return False
class DateTimeNotBetweenFilter(DateTimeBetweenFilter):
def apply(self, query, value):
......@@ -242,37 +262,17 @@ class TimeSmallerFilter(FilterSmaller, filters.BaseTimeFilter):
pass
class TimeBetweenFilter(BaseSQLAFilter):
class TimeBetweenFilter(BaseSQLAFilter, filters.BaseTimeBetweenFilter):
def __init__(self, column, name, options=None, data_type=None):
super(TimeBetweenFilter, self).__init__(column, name, options, data_type='timerangepicker')
def clean(self, value):
timetuples = [time.strptime(range, '%H:%M:%S')
for range in value.split(' to ')]
return [datetime.time(timetuple.tm_hour,
timetuple.tm_min,
timetuple.tm_sec)
for timetuple in timetuples]
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))
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
timetuples = [time.strptime(range, '%H:%M:%S')
for range in value.split(' to ')]
if (len(timetuples) == 2) and (timetuples[0] <= timetuples[1]):
return True
else:
return False
except ValueError:
raise
return False
class TimeNotBetweenFilter(TimeBetweenFilter):
def apply(self, query, value):
......@@ -285,17 +285,27 @@ class TimeNotBetweenFilter(TimeBetweenFilter):
# Base SQLA filter field converter
class FilterConverter(filters.BaseFilterConverter):
strings = (FilterEqual, FilterNotEqual, FilterLike, FilterNotLike, FilterEmpty, FilterInList, FilterNotInList)
numeric = (FilterEqual, FilterNotEqual, FilterGreater, FilterSmaller, FilterEmpty, FilterInList, FilterNotInList)
bool = (BooleanEqualFilter, BooleanNotEqualFilter)
enum = (FilterEqual, FilterNotEqual, FilterEmpty, FilterInList, FilterNotInList)
date_filters = (DateEqualFilter, DateNotEqualFilter, DateGreaterFilter, DateSmallerFilter,
DateBetweenFilter, DateNotBetweenFilter, FilterEmpty)
datetime_filters = (DateTimeEqualFilter, DateTimeNotEqualFilter, DateTimeGreaterFilter,
DateTimeSmallerFilter, DateTimeBetweenFilter, DateTimeNotBetweenFilter,
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)
enum = (FilterEqual, FilterNotEqual, FilterEmpty, FilterInList,
FilterNotInList)
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)
time_filters = (TimeEqualFilter, TimeNotEqualFilter, TimeGreaterFilter, TimeSmallerFilter,
TimeBetweenFilter, TimeNotBetweenFilter, FilterEmpty)
def convert(self, type_name, column, name, **kwargs):
if type_name.lower() in self.converters:
......@@ -310,13 +320,16 @@ class FilterConverter(filters.BaseFilterConverter):
@filters.convert('boolean', 'tinyint')
def conv_bool(self, column, name, **kwargs):
return [f(column, name, **kwargs) for f in self.bool]
return [f(column, name, **kwargs) for f in self.bool_filters]
@filters.convert('int', 'integer', 'smallinteger', 'smallint', 'numeric',
'float', 'real', 'biginteger', 'bigint', 'decimal',
'double_precision', 'double', 'mediumint')
'biginteger', 'bigint', 'mediumint')
def conv_int(self, column, name, **kwargs):
return [f(column, name, **kwargs) for f in self.numeric]
return [f(column, name, **kwargs) for f in self.int_filters]
@filters.convert('float', 'real', 'decimal', 'double_precision', 'double')
def conv_float(self, column, name, **kwargs):
return [f(column, name, **kwargs) for f in self.float_filters]
@filters.convert('date')
def conv_date(self, column, name, **kwargs):
......
......@@ -104,6 +104,38 @@ class BaseBooleanFilter(BaseFilter):
return value in ('0', '1')
class BaseIntFilter(BaseFilter):
"""
Base Int filter. Adds validation and changes value to python int.
"""
def clean(self, value):
return int(float(value))
class BaseFloatFilter(BaseFilter):
"""
Base Float filter. Adds validation and changes value to python float.
"""
def clean(self, value):
return float(value)
class BaseIntListFilter(BaseFilter):
"""
Base Integer list filter. Adds validation for int "In List" filter.
"""
def clean(self, value):
return [int(float(v.strip())) for v in value.split(',') if v.strip()]
class BaseFloatListFilter(BaseFilter):
"""
Base Float list filter. Adds validation for float "In List" filter.
"""
def clean(self, value):
return [float(v.strip()) for v in value.split(',') if v.strip()]
class BaseDateFilter(BaseFilter):
"""
Base Date filter. Uses client-side date picker control.
......@@ -117,6 +149,32 @@ class BaseDateFilter(BaseFilter):
return datetime.datetime.strptime(value, '%Y-%m-%d').date()
class BaseDateBetweenFilter(BaseFilter):
"""
Base Date Between filter. Consolidates logic for validation and clean.
Apply method is different for each back-end.
"""
def clean(self, value):
return [datetime.datetime.strptime(range, '%Y-%m-%d')
for range in value.split(' to ')]
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
value = [datetime.datetime.strptime(range, '%Y-%m-%d')
for range in value.split(' to ')]
# if " to " is missing, fail validation
# sqlalchemy's .between() will not work if end date is before start date
if (len(value) == 2) and (value[0] <= value[1]):
return True
else:
return False
except ValueError:
return False
class BaseDateTimeFilter(BaseFilter):
"""
Base DateTime filter. Uses client-side date time picker control.
......@@ -131,6 +189,30 @@ class BaseDateTimeFilter(BaseFilter):
return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
class BaseDateTimeBetweenFilter(BaseFilter):
"""
Base DateTime Between filter. Consolidates logic for validation and clean.
Apply method is different for each back-end.
"""
def clean(self, value):
return [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S')
for range in value.split(' to ')]
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
value = [datetime.datetime.strptime(range, '%Y-%m-%d %H:%M:%S')
for range in value.split(' to ')]
if (len(value) == 2) and (value[0] <= value[1]):
return True
else:
return False
except ValueError:
return False
class BaseTimeFilter(BaseFilter):
"""
Base Time filter. Uses client-side time picker control.
......@@ -148,6 +230,35 @@ class BaseTimeFilter(BaseFilter):
timetuple.tm_sec)
class BaseTimeBetweenFilter(BaseFilter):
"""
Base Time Between filter. Consolidates logic for validation and clean.
Apply method is different for each back-end.
"""
def clean(self, value):
timetuples = [time.strptime(range, '%H:%M:%S')
for range in value.split(' to ')]
return [datetime.time(timetuple.tm_hour,
timetuple.tm_min,
timetuple.tm_sec)
for timetuple in timetuples]
def operation(self):
return lazy_gettext('between')
def validate(self, value):
try:
timetuples = [time.strptime(range, '%H:%M:%S')
for range in value.split(' to ')]
if (len(timetuples) == 2) and (timetuples[0] <= timetuples[1]):
return True
else:
return False
except ValueError:
raise
return False
def convert(*args):
"""
Decorator for field to filter conversion routine.
......
......@@ -41,6 +41,7 @@ def create_models(db):
class Model2(db.Document):
string_field = db.StringField()
int_field = db.IntField()
float_field = db.FloatField()
bool_field = db.BooleanField()
model1 = db.ReferenceField(Model1)
......@@ -135,10 +136,10 @@ def test_column_filters():
Model1('test1_val_4', 'test2_val_4').save()
Model1(None, 'empty_obj').save()
Model2('string_field_val_1', None).save()
Model2('string_field_val_2', None).save()
Model2('string_field_val_3', 5000).save()
Model2('string_field_val_4', 9000).save()
Model2('string_field_val_1', None, None).save()
Model2('string_field_val_2', None, None).save()
Model2('string_field_val_3', 5000, 25.9).save()
Model2('string_field_val_4', 9000, 75.5).save()
Model1('datetime_obj1', datetime_field=datetime(2014,4,3,1,9,0)).save()
Model1('datetime_obj2', datetime_field=datetime(2013,3,2,0,8,0)).save()
......@@ -304,6 +305,86 @@ def test_column_filters():
ok_('string_field_val_3' not in data)
ok_('string_field_val_4' not in data)
# Test float filter
view = CustomModelView(Model2, column_filters=['float_field'],
endpoint="_float")
admin.add_view(view)
eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Float Field']],
[
(0, 'equals'),
(1, 'not equal'),
(2, 'greater than'),
(3, 'smaller than'),
(4, 'empty'),
(5, 'in list'),
(6, 'not in list'),
])
# float - equals
rv = client.get('/admin/_float/?flt0_0=25.9')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_3' in data)
ok_('string_field_val_4' not in data)
# float - not equal
rv = client.get('/admin/_float/?flt0_1=25.9')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_3' not in data)
ok_('string_field_val_4' in data)
# float - greater
rv = client.get('/admin/_float/?flt0_2=60.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_3' not in data)
ok_('string_field_val_4' in data)
# float - smaller
rv = client.get('/admin/_float/?flt0_3=60.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_3' in data)
ok_('string_field_val_4' not in data)
# float - empty
rv = client.get('/admin/_float/?flt0_4=1')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_1' in data)
ok_('string_field_val_2' in data)
ok_('string_field_val_3' not in data)
ok_('string_field_val_4' not in data)
# float - not empty
rv = client.get('/admin/_float/?flt0_4=0')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_1' not in data)
ok_('string_field_val_2' not in data)
ok_('string_field_val_3' in data)
ok_('string_field_val_4' in data)
# float - in list
rv = client.get('/admin/_float/?flt0_5=25.9%2C75.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_1' not in data)
ok_('string_field_val_2' not in data)
ok_('string_field_val_3' in data)
ok_('string_field_val_4' in data)
# float - not in list
rv = client.get('/admin/_float/?flt0_6=25.9%2C75.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('string_field_val_1' in data)
ok_('string_field_val_2' in data)
ok_('string_field_val_3' not in data)
ok_('string_field_val_4' not in data)
# Test datetime filter
view = CustomModelView(Model1,
column_filters=['datetime_field'],
......
......@@ -62,15 +62,18 @@ def create_models(db):
return self.test1
class Model2(BaseModel):
def __init__(self, char_field=None, int_field=None, bool_field=0):
def __init__(self, char_field=None, int_field=None, float_field=None,
bool_field=0):
super(Model2, self).__init__()
self.char_field = char_field
self.int_field = int_field
self.float_field = float_field
self.bool_field = bool_field
char_field = peewee.CharField(max_length=20)
int_field = peewee.IntegerField(null=True)
float_field = peewee.FloatField(null=True)
bool_field = peewee.BooleanField()
Model1.create_table()
......@@ -162,10 +165,10 @@ def test_column_filters():
Model1('test1_val_4', 'test2_val_4').save()
Model1(None, 'empty_obj').save()
Model2('char_field_val_1', None).save()
Model2('char_field_val_2', None).save()
Model2('char_field_val_3', 5000).save()
Model2('char_field_val_4', 9000).save()
Model2('char_field_val_1', None, None).save()
Model2('char_field_val_2', None, None).save()
Model2('char_field_val_3', 5000, 25.9).save()
Model2('char_field_val_4', 9000, 75.5).save()
Model1('date_obj1', date_field=date(2014,11,17)).save()
Model1('date_obj2', date_field=date(2013,10,16)).save()
......@@ -256,7 +259,7 @@ def test_column_filters():
ok_('test1_val_3' in data)
ok_('test1_val_4' in data)
# Test numeric filter
# Test int filter
view = CustomModelView(Model2, column_filters=['int_field'])
admin.add_view(view)
......@@ -335,6 +338,86 @@ def test_column_filters():
ok_('char_field_val_3' not in data)
ok_('char_field_val_4' not in data)
# Test float filter
view = CustomModelView(Model2, column_filters=['float_field'],
endpoint="_float")
admin.add_view(view)
eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Float Field']],
[
(0, 'equals'),
(1, 'not equal'),
(2, 'greater than'),
(3, 'smaller than'),
(4, 'empty'),
(5, 'in list'),
(6, 'not in list'),
])
# float - equals
rv = client.get('/admin/_float/?flt0_0=25.9')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_3' in data)
ok_('char_field_val_4' not in data)
# float - not equal
rv = client.get('/admin/_float/?flt0_1=25.9')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_3' not in data)
ok_('char_field_val_4' in data)
# float - greater
rv = client.get('/admin/_float/?flt0_2=60.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_3' not in data)
ok_('char_field_val_4' in data)
# float - smaller
rv = client.get('/admin/_float/?flt0_3=60.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_3' in data)
ok_('char_field_val_4' not in data)
# float - empty
rv = client.get('/admin/_float/?flt0_4=1')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_1' in data)
ok_('char_field_val_2' in data)
ok_('char_field_val_3' not in data)
ok_('char_field_val_4' not in data)
# float - not empty
rv = client.get('/admin/_float/?flt0_4=0')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_1' not in data)
ok_('char_field_val_2' not in data)
ok_('char_field_val_3' in data)
ok_('char_field_val_4' in data)
# float - in list
rv = client.get('/admin/_float/?flt0_5=25.9%2C75.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_1' not in data)
ok_('char_field_val_2' not in data)
ok_('char_field_val_3' in data)
ok_('char_field_val_4' in data)
# float - not in list
rv = client.get('/admin/_float/?flt0_6=25.9%2C75.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('char_field_val_1' in data)
ok_('char_field_val_2' in data)
ok_('char_field_val_3' not in data)
ok_('char_field_val_4' not in data)
# Test date, time, and datetime filters
view = CustomModelView(Model1,
column_filters=['date_field', 'datetime_field', 'timeonly_field'],
......
......@@ -57,17 +57,20 @@ def create_models(db):
return self.test1
class Model2(db.Model):
def __init__(self, string_field=None, int_field=None, bool_field=None, model1=None):
def __init__(self, string_field=None, int_field=None, bool_field=None,
model1=None, float_field=None):
self.string_field = string_field
self.int_field = int_field
self.bool_field = bool_field
self.model1 = model1
self.float_field = float_field
id = db.Column(db.Integer, primary_key=True)
string_field = db.Column(db.String)
int_field = db.Column(db.Integer)
bool_field = db.Column(db.Boolean)
enum_field = db.Column(db.Enum('model2_v1', 'model2_v2'), nullable=True)
float_field = db.Column(db.Float)
# Relation
model1_id = db.Column(db.Integer, db.ForeignKey(Model1.id))
......@@ -381,10 +384,10 @@ def test_column_filters():
model1_obj3 = Model1('test1_val_3', 'test2_val_3')
model1_obj4 = Model1('test1_val_4', 'test2_val_4')
model2_obj1 = Model2('test2_val_1', model1=model1_obj1)
model2_obj2 = Model2('test2_val_2', model1=model1_obj1)
model2_obj3 = Model2('test2_val_3', int_field=5000)
model2_obj4 = Model2('test2_val_4', int_field=9000)
model2_obj1 = Model2('test2_val_1', model1=model1_obj1, float_field=None)
model2_obj2 = Model2('test2_val_2', model1=model1_obj1, float_field=None)
model2_obj3 = Model2('test2_val_3', int_field=5000, float_field=25.9)
model2_obj4 = Model2('test2_val_4', int_field=9000, float_field=75.5)
date_obj1 = Model1('date_obj1', date_field=date(2014,11,17))
date_obj2 = Model1('date_obj2', date_field=date(2013,10,16))
......@@ -501,7 +504,7 @@ def test_column_filters():
ok_('test1_val_3' in data)
ok_('test1_val_4' in data)
# Test numeric filter
# Test integer filter
view = CustomModelView(Model2, db.session,
column_filters=['int_field'])
admin.add_view(view)
......@@ -581,6 +584,86 @@ def test_column_filters():
ok_('test2_val_3' not in data)
ok_('test2_val_4' not in data)
# Test float filter
view = CustomModelView(Model2, db.session, column_filters=['float_field'],
endpoint="_float")
admin.add_view(view)
eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Float Field']],
[
(0, 'equals'),
(1, 'not equal'),
(2, 'greater than'),
(3, 'smaller than'),
(4, 'empty'),
(5, 'in list'),
(6, 'not in list'),
])
# float - equals
rv = client.get('/admin/_float/?flt0_0=25.9')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_3' in data)
ok_('test2_val_4' not in data)
# float - not equal
rv = client.get('/admin/_float/?flt0_1=25.9')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_3' not in data)
ok_('test2_val_4' in data)
# float - greater
rv = client.get('/admin/_float/?flt0_2=60.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_3' not in data)
ok_('test2_val_4' in data)
# float - smaller
rv = client.get('/admin/_float/?flt0_3=60.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_3' in data)
ok_('test2_val_4' not in data)
# float - empty
rv = client.get('/admin/_float/?flt0_4=1')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_1' in data)
ok_('test2_val_2' in data)
ok_('test2_val_3' not in data)
ok_('test2_val_4' not in data)
# float - not empty
rv = client.get('/admin/_float/?flt0_4=0')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_1' not in data)
ok_('test2_val_2' not in data)
ok_('test2_val_3' in data)
ok_('test2_val_4' in data)
# float - in list
rv = client.get('/admin/_float/?flt0_5=25.9%2C75.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_1' not in data)
ok_('test2_val_2' not in data)
ok_('test2_val_3' in data)
ok_('test2_val_4' in data)
# float - not in list
rv = client.get('/admin/_float/?flt0_6=25.9%2C75.5')
eq_(rv.status_code, 200)
data = rv.data.decode('utf-8')
ok_('test2_val_1' in data)
ok_('test2_val_2' in data)
ok_('test2_val_3' not in data)
ok_('test2_val_4' not in data)
# Test filters to joined table field
view = CustomModelView(
Model2, db.session,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment