From 82f77ae364bd2a097fdae8d1862dc635e2193831 Mon Sep 17 00:00:00 2001 From: Ash Berlin-Taylor Date: Thu, 22 Oct 2020 23:00:31 +0100 Subject: [PATCH] Fix "actions" on ModelViews with composite primary keys The refactor in #1398 changes the `get()` function, and mistakenly always applied the PK filter, even in the case of composite keys. (The else block of `if self.is_pk_composite` applied it again, so it was actually applying the same filter twice, which didn't break anything, but was not needed) --- flask_appbuilder/models/sqla/interface.py | 1 - flask_appbuilder/tests/test_mvc.py | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/flask_appbuilder/models/sqla/interface.py b/flask_appbuilder/models/sqla/interface.py index d762e3d0c1..2431999e3a 100644 --- a/flask_appbuilder/models/sqla/interface.py +++ b/flask_appbuilder/models/sqla/interface.py @@ -917,7 +917,6 @@ def get( _filters = filters.copy() else: _filters = Filters(self.filter_converter_class, self) - _filters.add_filter(pk, self.FilterEqual, id) if self.is_pk_composite(): for _pk, _id in zip(pk, id): diff --git a/flask_appbuilder/tests/test_mvc.py b/flask_appbuilder/tests/test_mvc.py index e2f7fe53e5..7acb04b926 100644 --- a/flask_appbuilder/tests/test_mvc.py +++ b/flask_appbuilder/tests/test_mvc.py @@ -4,6 +4,7 @@ from typing import Set from flask import Flask, redirect, request, session +from flask_appbuilder.actions import action from flask_appbuilder import AppBuilder, SQLA from flask_appbuilder.charts.views import ( ChartView, @@ -389,6 +390,12 @@ class Model3View(ModelView): add_columns = ["pk1", "pk2", "field_string"] edit_columns = ["pk1", "pk2", "field_string"] + @action("muldelete", "Delete", "Delete all Really?", "fa-rocket", single=False) + def muldelete(self, items): + self.datamodel.delete_all(items) + self.update_redirect() + return redirect(self.get_redirect()) + class Model1CompactView(CompactCRUDMixin, ModelView): datamodel = SQLAInterface(Model1) @@ -829,6 +836,21 @@ def test_model_crud_composite_pk(self): model = self.db.session.query(Model3).filter_by(pk1=2).one_or_none() self.assertEqual(model, None) + # Add it back, then delete via muldelete + self.appbuilder.get_session.add(Model3(pk1=1, pk2=datetime.datetime(2017, 1, 1), field_string="baz")) + self.appbuilder.get_session.commit() + rv = client.post( + "/model3view/action_post", + data=dict( + action="muldelete", + rowid=[json.dumps(["1", {"_type": "datetime", "value": "2017-01-01T00:00:00.000000"}])], + ), + follow_redirects=True, + ) + self.assertEqual(rv.status_code, 200) + model = self.db.session.query(Model3).filter_by(pk1=1).one_or_none() + self.assertEqual(model, None) + def test_model_crud_add_with_enum(self): """ Test Model add for Model with Enum Columns