Skip to content

Commit 9065a9f

Browse files
duynguyenhoangDuy Nguyendpgaspar
authored
fix: issue 1469 error in filters (#1541)
Co-authored-by: Duy Nguyen <duy.nguyenhoang@global-fashion-group.com> Co-authored-by: Daniel Vaz Gaspar <danielvazgaspar@gmail.com>
1 parent 633cdc4 commit 9065a9f

4 files changed

Lines changed: 73 additions & 5 deletions

File tree

examples/extendsecurity/__init__.py

Whitespace-only changes.

flask_appbuilder/models/filters.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,10 @@ def _add_filter(self, filter_instance, value):
175175
def add_filter_index(
176176
self, column_name: str, filter_instance_index: int, value: Any
177177
):
178-
self._add_filter(self._all_filters[column_name][filter_instance_index], value)
178+
if column_name in self._all_filters.keys():
179+
self._add_filter(
180+
self._all_filters[column_name][filter_instance_index], value
181+
)
179182

180183
def rest_add_filters(self, data: List[Dict]) -> None:
181184
"""

flask_appbuilder/models/sqla/filters.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class FilterNotEqual(BaseFilter):
146146
def apply(self, query, value):
147147
query, field = get_field_setup_query(query, self.model, self.column_name)
148148
value = set_value_to_type(self.datamodel, self.column_name, value)
149+
149150
return query.filter(field != value)
150151

151152

@@ -156,6 +157,10 @@ class FilterGreater(BaseFilter):
156157
def apply(self, query, value):
157158
query, field = get_field_setup_query(query, self.model, self.column_name)
158159
value = set_value_to_type(self.datamodel, self.column_name, value)
160+
161+
if value is None:
162+
return query
163+
159164
return query.filter(field > value)
160165

161166

@@ -166,6 +171,10 @@ class FilterSmaller(BaseFilter):
166171
def apply(self, query, value):
167172
query, field = get_field_setup_query(query, self.model, self.column_name)
168173
value = set_value_to_type(self.datamodel, self.column_name, value)
174+
175+
if value is None:
176+
return query
177+
169178
return query.filter(field < value)
170179

171180

@@ -193,15 +202,33 @@ class FilterRelationManyToManyEqual(FilterRelation):
193202
name = lazy_gettext("Relation as Many")
194203
arg_name = "rel_m_m"
195204

205+
def apply_item(self, query, field, value_item):
206+
"""
207+
Get object by column_name and value_item, then apply filter if object exists
208+
Query with new filter applied
209+
"""
210+
rel_obj = self.datamodel.get_related_obj(self.column_name, value_item)
211+
212+
if rel_obj:
213+
return query.filter(field.contains(rel_obj))
214+
else:
215+
log.error(
216+
"Related object for column: %s, value: %s return Null",
217+
self.column_name,
218+
value_item,
219+
)
220+
221+
return query
222+
196223
def apply(self, query, value):
197224
query, field = get_field_setup_query(query, self.model, self.column_name)
225+
198226
if isinstance(value, list):
199227
for value_item in value:
200-
rel_obj = self.datamodel.get_related_obj(self.column_name, value_item)
201-
query = query.filter(field.contains(rel_obj))
228+
query = self.apply_item(query, field, value_item)
202229
return query
203-
rel_obj = self.datamodel.get_related_obj(self.column_name, value)
204-
return query.filter(field.contains(rel_obj))
230+
231+
return self.apply_item(query, field, value)
205232

206233

207234
class FilterEqualFunction(BaseFilter):

flask_appbuilder/tests/test_mvc.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,44 @@ def get_registered_view_endpoints(self, view_name) -> Set:
126126
}
127127

128128

129+
class ListFilterTestCase(BaseMVCTestCase):
130+
def test_list_filter_in_valid_object(self):
131+
"""
132+
MVC: Test Filter with related object not found
133+
"""
134+
with self.app.test_client() as c:
135+
self.browser_login(c, USERNAME_ADMIN, PASSWORD_ADMIN)
136+
137+
# Roles doesn't exists
138+
rv = c.get("/users/list/?_flt_0_roles=-1")
139+
self.assertEqual(rv.status_code, 200)
140+
141+
def test_list_filter_unknow_column(self):
142+
"""
143+
MVC: Test Filter with unknown field
144+
"""
145+
with self.app.test_client() as c:
146+
self.browser_login(c, USERNAME_ADMIN, PASSWORD_ADMIN)
147+
# UNKNOWN_COLUMN is not a valid column
148+
rv = c.get("/users/list/?_flt_0_UNKNOWN_COLUMN=-1")
149+
self.assertEqual(rv.status_code, 200)
150+
151+
def test_list_filter_invalid_value_format(self):
152+
"""
153+
MVC: Test Filter with invalid value of date filter
154+
"""
155+
with self.app.test_client() as c:
156+
self.browser_login(c, USERNAME_ADMIN, PASSWORD_ADMIN)
157+
158+
# Greater than wrong value
159+
rv = c.get("/users/list/?_flt_1_created_on=wrongvalue")
160+
self.assertEqual(rv.status_code, 200)
161+
162+
# Smaller than wrong value
163+
rv = c.get("/users/list/?_flt_2_created_on=wrongvalue")
164+
self.assertEqual(rv.status_code, 200)
165+
166+
129167
class MVCCSRFTestCase(BaseMVCTestCase):
130168
def setUp(self):
131169

0 commit comments

Comments
 (0)