From a528136ce74eed8d36cd69d976a63a0d58b0b64d Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 27 Oct 2023 14:13:42 -0700 Subject: [PATCH 1/5] Update ACM to v0.19 in requirements files --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index 70f92ba9..c5d881c8 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -21,7 +21,7 @@ django-login-required-middleware==0.8.0 # https://github.com/CleitonDeLima/djang django-dbbackup==4.0.1 # https://github.com/jazzband/django-dbbackup django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions -git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.17 +git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.19 # Simple history - model history tracking django-simple-history==3.1.1 # For tracking history From 9bf0f7d55d4903a887dfd779b77ca0ca96606f58 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 27 Oct 2023 14:22:30 -0700 Subject: [PATCH 2/5] Ignore any *.db file --- .gitignore | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index e9f9715d..18860960 100644 --- a/.gitignore +++ b/.gitignore @@ -279,9 +279,7 @@ gregor_django/media/ ### test db gregor_django.db +*.db ### dbbackups dbbackups/ - - - From 7846c9641d0bd541c0f1ca8516351dfc08844b8f Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 27 Oct 2023 14:22:38 -0700 Subject: [PATCH 3/5] Add workspace_form_class to workspace adapters This is required by the new version of ACM. --- gregor_django/gregor_anvil/adapters.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gregor_django/gregor_anvil/adapters.py b/gregor_django/gregor_anvil/adapters.py index 62e47330..eaea02cd 100644 --- a/gregor_django/gregor_anvil/adapters.py +++ b/gregor_django/gregor_anvil/adapters.py @@ -1,5 +1,6 @@ from anvil_consortium_manager.adapters.account import BaseAccountAdapter from anvil_consortium_manager.adapters.workspace import BaseWorkspaceAdapter +from anvil_consortium_manager.forms import WorkspaceForm from django.db.models import Q from . import forms, models, tables @@ -36,6 +37,7 @@ class UploadWorkspaceAdapter(BaseWorkspaceAdapter): list_table_class = tables.UploadWorkspaceTable workspace_data_model = models.UploadWorkspace workspace_data_form_class = forms.UploadWorkspaceForm + workspace_form_class = WorkspaceForm workspace_detail_template_name = "gregor_anvil/uploadworkspace_detail.html" def get_autocomplete_queryset(self, queryset, q, forwarded={}): @@ -66,6 +68,7 @@ class ExampleWorkspaceAdapter(BaseWorkspaceAdapter): workspace_data_model = models.ExampleWorkspace workspace_data_form_class = forms.ExampleWorkspaceForm workspace_detail_template_name = "anvil_consortium_manager/workspace_detail.html" + workspace_form_class = WorkspaceForm class TemplateWorkspaceAdapter(BaseWorkspaceAdapter): @@ -78,6 +81,7 @@ class TemplateWorkspaceAdapter(BaseWorkspaceAdapter): workspace_data_model = models.TemplateWorkspace workspace_data_form_class = forms.TemplateWorkspaceForm workspace_detail_template_name = "gregor_anvil/templateworkspace_detail.html" + workspace_form_class = WorkspaceForm class CombinedConsortiumDataWorkspaceAdapter(BaseWorkspaceAdapter): @@ -92,6 +96,7 @@ class CombinedConsortiumDataWorkspaceAdapter(BaseWorkspaceAdapter): workspace_detail_template_name = ( "gregor_anvil/combinedconsortiumdataworkspace_detail.html" ) + workspace_form_class = WorkspaceForm class ReleaseWorkspaceAdapter(BaseWorkspaceAdapter): @@ -104,6 +109,7 @@ class ReleaseWorkspaceAdapter(BaseWorkspaceAdapter): workspace_data_model = models.ReleaseWorkspace workspace_data_form_class = forms.ReleaseWorkspaceForm workspace_detail_template_name = "gregor_anvil/releaseworkspace_detail.html" + workspace_form_class = WorkspaceForm class DCCProcessingWorkspaceAdapter(BaseWorkspaceAdapter): @@ -116,6 +122,7 @@ class DCCProcessingWorkspaceAdapter(BaseWorkspaceAdapter): workspace_data_model = models.DCCProcessingWorkspace workspace_data_form_class = forms.DCCProcessingWorkspaceForm workspace_detail_template_name = "gregor_anvil/dccprocessingworkspace_detail.html" + workspace_form_class = WorkspaceForm class DCCProcessedDataWorkspaceAdapter(BaseWorkspaceAdapter): @@ -130,3 +137,4 @@ class DCCProcessedDataWorkspaceAdapter(BaseWorkspaceAdapter): workspace_detail_template_name = ( "gregor_anvil/dccprocesseddataworkspace_detail.html" ) + workspace_form_class = WorkspaceForm From a28241eafa4706955a5dd4fc34ba0829b050b35d Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 27 Oct 2023 16:02:49 -0700 Subject: [PATCH 4/5] Update AccountAdapter to use default list filter Also add crispy_bootstrap5 to the installed apps, which is required to use the crispy form for the list filtering. --- config/settings/base.py | 1 + gregor_django/gregor_anvil/adapters.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/config/settings/base.py b/config/settings/base.py index 0f4e6db1..b92cc0eb 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -72,6 +72,7 @@ ] THIRD_PARTY_APPS = [ "crispy_forms", + "crispy_bootstrap5", "allauth", "allauth.account", "allauth.socialaccount", diff --git a/gregor_django/gregor_anvil/adapters.py b/gregor_django/gregor_anvil/adapters.py index eaea02cd..26d5db14 100644 --- a/gregor_django/gregor_anvil/adapters.py +++ b/gregor_django/gregor_anvil/adapters.py @@ -1,5 +1,6 @@ from anvil_consortium_manager.adapters.account import BaseAccountAdapter from anvil_consortium_manager.adapters.workspace import BaseWorkspaceAdapter +from anvil_consortium_manager.filters import AccountListFilter from anvil_consortium_manager.forms import WorkspaceForm from django.db.models import Q @@ -10,6 +11,7 @@ class AccountAdapter(BaseAccountAdapter): """Custom account adapter for PRIMED.""" list_table_class = tables.AccountTable + list_filterset_class = AccountListFilter def get_autocomplete_queryset(self, queryset, q): """Filter to Accounts where the email or the associated user name matches the query `q`.""" From c9fdefc8f33e2d89d4f972fa92388b51b183c591 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Fri, 27 Oct 2023 16:40:42 -0700 Subject: [PATCH 5/5] Add a custom AccountListFilter with linked user's name --- gregor_django/gregor_anvil/adapters.py | 5 ++-- gregor_django/gregor_anvil/filters.py | 10 +++++++ .../gregor_anvil/tests/test_views.py | 28 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 gregor_django/gregor_anvil/filters.py diff --git a/gregor_django/gregor_anvil/adapters.py b/gregor_django/gregor_anvil/adapters.py index 26d5db14..30af25e0 100644 --- a/gregor_django/gregor_anvil/adapters.py +++ b/gregor_django/gregor_anvil/adapters.py @@ -1,17 +1,16 @@ from anvil_consortium_manager.adapters.account import BaseAccountAdapter from anvil_consortium_manager.adapters.workspace import BaseWorkspaceAdapter -from anvil_consortium_manager.filters import AccountListFilter from anvil_consortium_manager.forms import WorkspaceForm from django.db.models import Q -from . import forms, models, tables +from . import filters, forms, models, tables class AccountAdapter(BaseAccountAdapter): """Custom account adapter for PRIMED.""" list_table_class = tables.AccountTable - list_filterset_class = AccountListFilter + list_filterset_class = filters.AccountListFilter def get_autocomplete_queryset(self, queryset, q): """Filter to Accounts where the email or the associated user name matches the query `q`.""" diff --git a/gregor_django/gregor_anvil/filters.py b/gregor_django/gregor_anvil/filters.py new file mode 100644 index 00000000..6100777d --- /dev/null +++ b/gregor_django/gregor_anvil/filters.py @@ -0,0 +1,10 @@ +from anvil_consortium_manager.forms import FilterForm +from anvil_consortium_manager.models import Account +from django_filters import FilterSet + + +class AccountListFilter(FilterSet): + class Meta: + model = Account + fields = {"email": ["icontains"], "user__name": ["icontains"]} + form = FilterForm diff --git a/gregor_django/gregor_anvil/tests/test_views.py b/gregor_django/gregor_anvil/tests/test_views.py index 0e7311da..bc93214d 100644 --- a/gregor_django/gregor_anvil/tests/test_views.py +++ b/gregor_django/gregor_anvil/tests/test_views.py @@ -948,6 +948,34 @@ def test_view_with_two_objects(self): self.assertEqual(len(response.context_data["table"].rows), 2) +class AccountListTest(TestCase): + def setUp(self): + """Set up test class.""" + self.factory = RequestFactory() + # Create a user with both view and edit permission. + self.user = User.objects.create_user(username="test", password="test") + self.user.user_permissions.add( + Permission.objects.get( + codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME + ) + ) + + def test_filter_by_name(self): + """Filtering by name works as expected.""" + user = UserFactory.create(name="First Last") + account = acm_factories.AccountFactory.create(user=user) + other_account = acm_factories.AccountFactory.create(verified=True) + self.client.force_login(self.user) + response = self.client.get( + reverse("anvil_consortium_manager:accounts:list"), + {"user__name__icontains": "First"}, + ) + self.assertIn("table", response.context_data) + self.assertEqual(len(response.context_data["table"].rows), 1) + self.assertIn(account, response.context_data["table"].data) + self.assertNotIn(other_account, response.context_data["table"].data) + + class UploadWorkspaceDetailTest(TestCase): """Tests of the anvil_consortium_manager WorkspaceDetail view using the UploadWorkspace adapter."""