def test_column_filters():
    app, db, admin = setup()

    Model1, Model2 = create_models(db)

    view = CustomModelView(
        Model1, db.session,
        column_filters=['test1']
    )
    admin.add_view(view)

    client = app.test_client()

    eq_(len(view._filters), 7)

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Test1']],
        [
            (0, u'contains'),
            (1, u'not contains'),
            (2, u'equals'),
            (3, u'not equal'),
            (4, u'empty'),
            (5, u'in list'),
            (6, u'not in list'),
        ])

    # Test filter that references property
    view = CustomModelView(Model2, db.session,
                           column_filters=['model1'])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Model1 / Test1']],
        [
            (0, u'contains'),
            (1, u'not contains'),
            (2, u'equals'),
            (3, u'not equal'),
            (4, u'empty'),
            (5, u'in list'),
            (6, u'not in list'),
        ])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Model1 / Test2']],
        [
            (7, u'contains'),
            (8, u'not contains'),
            (9, u'equals'),
            (10, u'not equal'),
            (11, u'empty'),
            (12, u'in list'),
            (13, u'not in list'),
        ])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Model1 / Test3']],
        [
            (14, u'contains'),
            (15, u'not contains'),
            (16, u'equals'),
            (17, u'not equal'),
            (18, u'empty'),
            (19, u'in list'),
            (20, u'not in list'),
        ])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Model1 / Test4']],
        [
            (21, u'contains'),
            (22, u'not contains'),
            (23, u'equals'),
            (24, u'not equal'),
            (25, u'empty'),
            (26, u'in list'),
            (27, u'not in list'),
        ])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Model1 / Bool Field']],
        [
            (28, u'equals'),
            (29, u'not equal'),
        ])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Model1 / Enum Field']],
        [
            (30, u'equals'),
            (31, u'not equal'),
            (32, u'empty'),
            (33, u'in list'),
            (34, u'not in list'),
        ])

    # Test filter with a dot
    view = CustomModelView(Model2, db.session,
                           column_filters=['model1.bool_field'])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Model1 / Bool Field']],
        [
            (0, 'equals'),
            (1, 'not equal'),
        ])

    # Test column_labels on filters
    view = CustomModelView(Model2, db.session,
                           column_filters=['model1.bool_field', 'string_field'],
                           column_labels={
                               'model1.bool_field': 'Test Filter #1',
                               'string_field': 'Test Filter #2',
                           })

    eq_(list(view._filter_groups.keys()), [u'Test Filter #1', u'Test Filter #2'])

    fill_db(db, Model1, Model2)

    # Test equals
    rv = client.get('/admin/model1/?flt0_0=test1_val_1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    # the filter value is always in "data"
    # need to check a different column than test1 for the expected row

    ok_('test2_val_1' in data)
    ok_('test1_val_2' not in data)

    # Test NOT IN filter
    rv = client.get('/admin/model1/?flt0_6=test1_val_1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')

    ok_('test1_val_2' in data)
    ok_('test2_val_1' not in data)

    # Test string filter
    view = CustomModelView(Model1, db.session,
                           column_filters=['test1'], endpoint='_strings')
    admin.add_view(view)

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Test1']],
        [
            (0, 'contains'),
            (1, 'not contains'),
            (2, 'equals'),
            (3, 'not equal'),
            (4, 'empty'),
            (5, 'in list'),
            (6, 'not in list'),
        ])

    # string - equals
    rv = client.get('/admin/_strings/?flt0_0=test1_val_1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' in data)
    ok_('test1_val_2' not in data)

    # string - not equal
    rv = client.get('/admin/_strings/?flt0_1=test1_val_1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' not in data)
    ok_('test1_val_2' in data)

    # string - contains
    rv = client.get('/admin/_strings/?flt0_2=test1_val_1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' in data)
    ok_('test1_val_2' not in data)

    # string - not contains
    rv = client.get('/admin/_strings/?flt0_3=test1_val_1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' not in data)
    ok_('test1_val_2' in data)

    # string - empty
    rv = client.get('/admin/_strings/?flt0_4=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('empty_obj' in data)
    ok_('test1_val_1' not in data)
    ok_('test1_val_2' not in data)

    # string - not empty
    rv = client.get('/admin/_strings/?flt0_4=0')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('empty_obj' not in data)
    ok_('test1_val_1' in data)
    ok_('test1_val_2' in data)

    # string - in list
    rv = client.get('/admin/_strings/?flt0_5=test1_val_1%2Ctest1_val_2')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' in data)
    ok_('test2_val_2' in data)
    ok_('test1_val_3' not in data)
    ok_('test1_val_4' not in data)

    # string - not in list
    rv = client.get('/admin/_strings/?flt0_6=test1_val_1%2Ctest1_val_2')
    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_('test1_val_3' in data)
    ok_('test1_val_4' in data)

    # Test integer filter
    view = CustomModelView(Model2, db.session,
                           column_filters=['int_field'])
    admin.add_view(view)

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Int Field']],
        [
            (0, 'equals'),
            (1, 'not equal'),
            (2, 'greater than'),
            (3, 'smaller than'),
            (4, 'empty'),
            (5, 'in list'),
            (6, 'not in list'),
        ])

    # integer - equals
    rv = client.get('/admin/model2/?flt0_0=5000')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_3' in data)
    ok_('test2_val_4' not in data)

    # integer - equals (huge number)
    rv = client.get('/admin/model2/?flt0_0=6169453081680413441')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_5' in data)
    ok_('test2_val_4' not in data)

    # integer - equals - test validation
    rv = client.get('/admin/model2/?flt0_0=badval')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('Invalid Filter Value' in data)

    # integer - not equal
    rv = client.get('/admin/model2/?flt0_1=5000')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_3' not in data)
    ok_('test2_val_4' in data)

    # integer - greater
    rv = client.get('/admin/model2/?flt0_2=6000')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_3' not in data)
    ok_('test2_val_4' in data)

    # integer - smaller
    rv = client.get('/admin/model2/?flt0_3=6000')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_3' in data)
    ok_('test2_val_4' not in data)

    # integer - empty
    rv = client.get('/admin/model2/?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)

    # integer - not empty
    rv = client.get('/admin/model2/?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)

    # integer - in list
    rv = client.get('/admin/model2/?flt0_5=5000%2C9000')
    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)

    # integer - in list (huge number)
    rv = client.get('/admin/model2/?flt0_5=6169453081680413441')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' not in data)
    ok_('test2_val_5' in data)

    # integer - in list - test validation
    rv = client.get('/admin/model2/?flt0_5=5000%2Cbadval')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('Invalid Filter Value' in data)

    # integer - not in list
    rv = client.get('/admin/model2/?flt0_6=5000%2C9000')
    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 boolean filter
    view = CustomModelView(Model1, db.session, column_filters=['bool_field'],
                           endpoint="_bools")
    admin.add_view(view)

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Bool Field']],
        [
            (0, 'equals'),
            (1, 'not equal'),
        ])

    # boolean - equals - Yes
    rv = client.get('/admin/_bools/?flt0_0=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' in data)
    ok_('test2_val_2' not in data)
    ok_('test2_val_3' not in data)

    # boolean - equals - No
    rv = client.get('/admin/_bools/?flt0_0=0')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' not in data)
    ok_('test2_val_2' in data)
    ok_('test2_val_3' in data)

    # boolean - not equals - Yes
    rv = client.get('/admin/_bools/?flt0_1=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' not in data)
    ok_('test2_val_2' in data)
    ok_('test2_val_3' in data)

    # boolean - not equals - No
    rv = client.get('/admin/_bools/?flt0_1=0')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' in data)
    ok_('test2_val_2' not in data)
    ok_('test2_val_3' 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 - equals - test validation
    rv = client.get('/admin/_float/?flt0_0=badval')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('Invalid Filter Value' 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 - in list - test validation
    rv = client.get('/admin/_float/?flt0_5=25.9%2Cbadval')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('Invalid Filter Value' 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,
        endpoint='_model2',
        column_filters=['model1.bool_field'],
        column_list=[
            'string_field',
            'model1.id',
            'model1.bool_field',
        ]
    )
    admin.add_view(view)

    rv = client.get('/admin/_model2/?flt1_0=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test2_val_1' in data)
    ok_('test2_val_2' not in data)
    ok_('test2_val_3' not in data)
    ok_('test2_val_4' not in data)

    # Test human readable URLs
    view = CustomModelView(
        Model1, db.session,
        column_filters=['test1'],
        endpoint='_model3',
        named_filter_urls=True
    )
    admin.add_view(view)

    rv = client.get('/admin/_model3/?flt1_test1_equals=test1_val_1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' in data)
    ok_('test1_val_2' not in data)

    # Test date, time, and datetime filters
    view = CustomModelView(Model1, db.session,
                           column_filters=['date_field', 'datetime_field', 'time_field'],
                           endpoint="_datetime")
    admin.add_view(view)

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Date Field']],
        [
            (0, 'equals'),
            (1, 'not equal'),
            (2, 'greater than'),
            (3, 'smaller than'),
            (4, 'between'),
            (5, 'not between'),
            (6, 'empty'),
        ])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Datetime Field']],
        [
            (7, 'equals'),
            (8, 'not equal'),
            (9, 'greater than'),
            (10, 'smaller than'),
            (11, 'between'),
            (12, 'not between'),
            (13, 'empty'),
        ])

    eq_([(f['index'], f['operation']) for f in view._filter_groups[u'Time Field']],
        [
            (14, 'equals'),
            (15, 'not equal'),
            (16, 'greater than'),
            (17, 'smaller than'),
            (18, 'between'),
            (19, 'not between'),
            (20, 'empty'),
        ])

    # date - equals
    rv = client.get('/admin/_datetime/?flt0_0=2014-11-17')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('date_obj1' in data)
    ok_('date_obj2' not in data)

    # date - not equal
    rv = client.get('/admin/_datetime/?flt0_1=2014-11-17')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('date_obj1' not in data)
    ok_('date_obj2' in data)

    # date - greater
    rv = client.get('/admin/_datetime/?flt0_2=2014-11-16')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('date_obj1' in data)
    ok_('date_obj2' not in data)

    # date - smaller
    rv = client.get('/admin/_datetime/?flt0_3=2014-11-16')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('date_obj1' not in data)
    ok_('date_obj2' in data)

    # date - between
    rv = client.get('/admin/_datetime/?flt0_4=2014-11-13+to+2014-11-20')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('date_obj1' in data)
    ok_('date_obj2' not in data)

    # date - not between
    rv = client.get('/admin/_datetime/?flt0_5=2014-11-13+to+2014-11-20')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('date_obj1' not in data)
    ok_('date_obj2' in data)

    # date - empty
    rv = client.get('/admin/_datetime/?flt0_6=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' in data)
    ok_('date_obj1' not in data)
    ok_('date_obj2' not in data)

    # date - empty
    rv = client.get('/admin/_datetime/?flt0_6=0')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' not in data)
    ok_('date_obj1' in data)
    ok_('date_obj2' in data)

    # datetime - equals
    rv = client.get('/admin/_datetime/?flt0_7=2014-04-03+01%3A09%3A00')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('datetime_obj1' in data)
    ok_('datetime_obj2' not in data)

    # datetime - not equal
    rv = client.get('/admin/_datetime/?flt0_8=2014-04-03+01%3A09%3A00')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('datetime_obj1' not in data)
    ok_('datetime_obj2' in data)

    # datetime - greater
    rv = client.get('/admin/_datetime/?flt0_9=2014-04-03+01%3A08%3A00')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('datetime_obj1' in data)
    ok_('datetime_obj2' not in data)

    # datetime - smaller
    rv = client.get('/admin/_datetime/?flt0_10=2014-04-03+01%3A08%3A00')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('datetime_obj1' not in data)
    ok_('datetime_obj2' in data)

    # datetime - between
    rv = client.get('/admin/_datetime/?flt0_11=2014-04-02+00%3A00%3A00+to+2014-11-20+23%3A59%3A59')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('datetime_obj1' in data)
    ok_('datetime_obj2' not in data)

    # datetime - not between
    rv = client.get('/admin/_datetime/?flt0_12=2014-04-02+00%3A00%3A00+to+2014-11-20+23%3A59%3A59')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('datetime_obj1' not in data)
    ok_('datetime_obj2' in data)

    # datetime - empty
    rv = client.get('/admin/_datetime/?flt0_13=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' in data)
    ok_('datetime_obj1' not in data)
    ok_('datetime_obj2' not in data)

    # datetime - not empty
    rv = client.get('/admin/_datetime/?flt0_13=0')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' not in data)
    ok_('datetime_obj1' in data)
    ok_('datetime_obj2' in data)

    # time - equals
    rv = client.get('/admin/_datetime/?flt0_14=11%3A10%3A09')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('timeonly_obj1' in data)
    ok_('timeonly_obj2' not in data)

    # time - not equal
    rv = client.get('/admin/_datetime/?flt0_15=11%3A10%3A09')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('timeonly_obj1' not in data)
    ok_('timeonly_obj2' in data)

    # time - greater
    rv = client.get('/admin/_datetime/?flt0_16=11%3A09%3A09')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('timeonly_obj1' in data)
    ok_('timeonly_obj2' not in data)

    # time - smaller
    rv = client.get('/admin/_datetime/?flt0_17=11%3A09%3A09')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('timeonly_obj1' not in data)
    ok_('timeonly_obj2' in data)

    # time - between
    rv = client.get('/admin/_datetime/?flt0_18=10%3A40%3A00+to+11%3A50%3A59')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('timeonly_obj1' in data)
    ok_('timeonly_obj2' not in data)

    # time - not between
    rv = client.get('/admin/_datetime/?flt0_19=10%3A40%3A00+to+11%3A50%3A59')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('timeonly_obj1' not in data)
    ok_('timeonly_obj2' in data)

    # time - empty
    rv = client.get('/admin/_datetime/?flt0_20=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' in data)
    ok_('timeonly_obj1' not in data)
    ok_('timeonly_obj2' not in data)

    # time - not empty
    rv = client.get('/admin/_datetime/?flt0_20=0')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' not in data)
    ok_('timeonly_obj1' in data)
    ok_('timeonly_obj2' in data)

    # Test enum filter
    view = CustomModelView(Model1, db.session,
                           column_filters=['enum_field'],
                           endpoint="_enumfield")
    admin.add_view(view)

    # enum - equals
    rv = client.get('/admin/_enumfield/?flt0_0=model1_v1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('enum_obj1' in data)
    ok_('enum_obj2' not in data)

    # enum - not equal
    rv = client.get('/admin/_enumfield/?flt0_1=model1_v1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('enum_obj1' not in data)
    ok_('enum_obj2' in data)

    # enum - empty
    rv = client.get('/admin/_enumfield/?flt0_2=1')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' in data)
    ok_('enum_obj1' not in data)
    ok_('enum_obj2' not in data)

    # enum - not empty
    rv = client.get('/admin/_enumfield/?flt0_2=0')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' not in data)
    ok_('enum_obj1' in data)
    ok_('enum_obj2' in data)

    # enum - in list
    rv = client.get('/admin/_enumfield/?flt0_3=model1_v1%2Cmodel1_v2')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' not in data)
    ok_('enum_obj1' in data)
    ok_('enum_obj2' in data)

    # enum - not in list
    rv = client.get('/admin/_enumfield/?flt0_4=model1_v1%2Cmodel1_v2')
    eq_(rv.status_code, 200)
    data = rv.data.decode('utf-8')
    ok_('test1_val_1' in data)
    ok_('enum_obj1' not in data)
    ok_('enum_obj2' not in data)

    # Test single custom filter on relation
    view = CustomModelView(Model2, db.session,
                           column_filters = [
                               filters.FilterEqual(Model1.test1, "Test1")
                           ], endpoint='_relation_test')
    admin.add_view(view)

    rv = client.get('/admin/_relation_test/?flt1_0=test1_val_1')
    data = rv.data.decode('utf-8')

    ok_('test1_val_1' in data)
    ok_('test1_val_2' not in data)
dataset/ETHPy150Open flask-admin/flask-admin/flask_admin/tests/sqla/test_basic.py/test_column_filters/original