diff --git a/explorer/templates/explorer/querylog_list.html b/explorer/templates/explorer/querylog_list.html index 32b2f4d5..63aa423a 100644 --- a/explorer/templates/explorer/querylog_list.html +++ b/explorer/templates/explorer/querylog_list.html @@ -4,6 +4,28 @@ {% block sql_explorer_content %}

{% blocktranslate with pagenum=page_obj.number %}Recent Query Logs - Page {{pagenum}}{% endblocktranslate %}

+
+ {% if query_id %}{% endif %} +
+ + +
+
+
+ + +
+
+
+ + {% translate "Clear" %} +
+
@@ -50,7 +72,7 @@

{% blocktranslate with pagenum=page_obj.number %}Recent Query Logs - Page {{ diff --git a/explorer/tests/test_views.py b/explorer/tests/test_views.py index fc863de4..e0eaed62 100644 --- a/explorer/tests/test_views.py +++ b/explorer/tests/test_views.py @@ -809,6 +809,28 @@ def test_query_gets_logged_and_appears_on_log_page(self): resp = self.client.get(reverse("explorer_logs")) self.assertContains(resp, "select 12345;") + def test_filter_logs_by_connection(self): + other_conn = DatabaseConnection.objects.create( + alias="filter_conn", engine="django.db.backends.sqlite3", name=":memory:" + ) + QueryLogFactory(sql="select default conn;") + QueryLogFactory(sql="select other conn;", database_connection_id=other_conn.id) + resp = self.client.get(f"{reverse('explorer_logs')}?connection={other_conn.id}") + self.assertContains(resp, "select other conn;") + self.assertNotContains(resp, "select default conn;") + # an invalid connection value is ignored and shows everything + resp = self.client.get(f"{reverse('explorer_logs')}?connection=notanid") + self.assertContains(resp, "select other conn;") + self.assertContains(resp, "select default conn;") + + def test_filter_logs_run_by_me(self): + other = User.objects.create_superuser("other", "other@other.com", "pwd") + QueryLogFactory(sql="select mine;", run_by_user=self.user) + QueryLogFactory(sql="select theirs;", run_by_user=other) + resp = self.client.get(f"{reverse('explorer_logs')}?run_by_me=1") + self.assertContains(resp, "select mine;") + self.assertNotContains(resp, "select theirs;") + def test_admin_required(self): self.client.logout() resp = self.client.get(reverse("explorer_logs")) diff --git a/explorer/views/list.py b/explorer/views/list.py index 133980ee..76d9a0cd 100644 --- a/explorer/views/list.py +++ b/explorer/views/list.py @@ -6,7 +6,7 @@ from explorer import app_settings from explorer.models import Query, QueryFavorite, QueryLog -from explorer.utils import allowed_query_pks, url_get_query_id +from explorer.utils import allowed_query_pks, get_int_from_request, url_get_query_id from explorer.views.auth import PermissionRequiredMixin from explorer.views.mixins import ExplorerContextMixin from explorer.ee.db_connections.models import DatabaseConnection @@ -136,4 +136,21 @@ def get_queryset(self): kwargs = {"sql__isnull": False} if url_get_query_id(self.request): kwargs["query_id"] = url_get_query_id(self.request) + connection_id = get_int_from_request(self.request, "connection", None) + if connection_id: + kwargs["database_connection_id"] = connection_id + if self.request.GET.get("run_by_me") and self.request.user.is_authenticated: + kwargs["run_by_user"] = self.request.user return QueryLog.objects.filter(**kwargs).all() + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + params = self.request.GET.copy() + if "page" in params: + del params["page"] + context["database_connections"] = DatabaseConnection.objects.all() + context["selected_connection"] = get_int_from_request(self.request, "connection", None) + context["run_by_me"] = bool(self.request.GET.get("run_by_me")) + context["query_id"] = url_get_query_id(self.request) + context["filter_querystring"] = params.urlencode() + return context