[dashboards] New, tittle and slug OR filter (#9435)

* [dashboards] New, tittle and slug OR filter

* Update requirements, because of prison bump

* Tests

* Fix tests

* Avoid like filter on empty string value

* merge master brings strict typing to the table
This commit is contained in:
Daniel Vaz Gaspar
2020-04-09 11:14:28 +01:00
committed by GitHub
parent bb80ceaccc
commit b39e78fca5
3 changed files with 56 additions and 1 deletions

View File

@@ -36,7 +36,7 @@ from superset.dashboards.commands.exceptions import (
DashboardUpdateFailedError,
)
from superset.dashboards.commands.update import UpdateDashboardCommand
from superset.dashboards.filters import DashboardFilter
from superset.dashboards.filters import DashboardFilter, DashboardTitleOrSlugFilter
from superset.dashboards.schemas import (
DashboardPostSchema,
DashboardPutSchema,
@@ -104,6 +104,7 @@ class DashboardRestApi(BaseSupersetModelRestApi):
"published",
]
search_columns = ("dashboard_title", "slug", "owners", "published")
search_filters = {"dashboard_title": [DashboardTitleOrSlugFilter]}
add_columns = edit_columns
base_order = ("changed_on", "desc")

View File

@@ -16,6 +16,7 @@
# under the License.
from typing import Any
from flask_babel import lazy_gettext as _
from sqlalchemy import and_, or_
from sqlalchemy.orm.query import Query
@@ -26,6 +27,22 @@ from superset.models.slice import Slice
from superset.views.base import BaseFilter, get_user_roles
class DashboardTitleOrSlugFilter(BaseFilter): # pylint: disable=too-few-public-methods
name = _("Title or Slug")
arg_name = "title_or_slug"
def apply(self, query: Query, value: Any) -> Query:
if not value:
return query
ilike_value = f"%{value}%"
return query.filter(
or_(
Dashboard.dashboard_title.ilike(ilike_value),
Dashboard.slug.ilike(ilike_value),
)
)
class DashboardFilter(BaseFilter): # pylint: disable=too-few-public-methods
"""
List dashboards with the following criteria:

View File

@@ -179,6 +179,43 @@ class DashboardApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
db.session.delete(dashboard)
db.session.commit()
def test_get_dashboards_custom_filter(self):
"""
Dashboard API: Test get dashboards custom filter
"""
admin = self.get_user("admin")
dashboard1 = self.insert_dashboard("foo", "ZY_bar", [admin.id])
dashboard2 = self.insert_dashboard("zy_foo", "slug1", [admin.id])
dashboard3 = self.insert_dashboard("foo", "slug1zy_", [admin.id])
dashboard4 = self.insert_dashboard("bar", "foo", [admin.id])
arguments = {
"filters": [
{"col": "dashboard_title", "opr": "title_or_slug", "value": "zy_"}
]
}
self.login(username="admin")
uri = f"api/v1/dashboard/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 3)
self.logout()
self.login(username="gamma")
uri = f"api/v1/dashboard/?q={prison.dumps(arguments)}"
rv = self.client.get(uri)
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 0)
# rollback changes
db.session.delete(dashboard1)
db.session.delete(dashboard2)
db.session.delete(dashboard3)
db.session.delete(dashboard4)
db.session.commit()
def test_get_dashboards_no_data_access(self):
"""
Dashboard API: Test get dashboards no data access