mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
[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:
committed by
GitHub
parent
bb80ceaccc
commit
b39e78fca5
@@ -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")
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user