From a52c8611bd0ff65f7fef6ba6a1114608c06c47cf Mon Sep 17 00:00:00 2001 From: Hironsan Date: Wed, 12 Jan 2022 14:58:37 +0900 Subject: [PATCH] Add a filter to MemberListAPI --- backend/roles/tests.py | 20 ++++++++++++++++---- backend/roles/urls.py | 14 +++++++------- backend/roles/views.py | 36 ++++++++++++++++++------------------ 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/backend/roles/tests.py b/backend/roles/tests.py index 077e69e4..c43f0a8f 100644 --- a/backend/roles/tests.py +++ b/backend/roles/tests.py @@ -22,14 +22,14 @@ class TestRoleAPI(CRUDMixin): self.assert_fetch(expected=status.HTTP_403_FORBIDDEN) -class TestRoleMappingListAPI(CRUDMixin): +class TestMemberListAPI(CRUDMixin): def setUp(self): self.project = prepare_project() self.non_member = make_user() admin_role = Role.objects.get(name=settings.ROLE_PROJECT_ADMIN) self.data = {'user': self.non_member.id, 'role': admin_role.id, 'project': self.project.item.id} - self.url = reverse(viewname='rolemapping_list', args=[self.project.item.id]) + self.url = reverse(viewname='member_list', args=[self.project.item.id]) def test_allows_project_admin_to_get_mappings(self): self.assert_fetch(self.project.users[0], status.HTTP_200_OK) @@ -80,14 +80,14 @@ class TestRoleMappingListAPI(CRUDMixin): self.assert_bulk_delete(expected=status.HTTP_403_FORBIDDEN) -class TestRoleMappingDetailAPI(CRUDMixin): +class TestMemberRoleDetailAPI(CRUDMixin): def setUp(self): self.project = prepare_project() self.non_member = make_user() admin_role = Role.objects.get(name=settings.ROLE_PROJECT_ADMIN) mapping = RoleMapping.objects.get(user=self.project.users[1]) - self.url = reverse(viewname='rolemapping_detail', args=[self.project.item.id, mapping.id]) + self.url = reverse(viewname='member_detail', args=[self.project.item.id, mapping.id]) self.data = {'role': admin_role.id} def test_allows_project_admin_to_get_mapping(self): @@ -115,3 +115,15 @@ class TestRoleMappingDetailAPI(CRUDMixin): def test_denies_unauthenticated_user_to_update_mapping(self): self.assert_update(expected=status.HTTP_403_FORBIDDEN) + + +class TestMemberRoleFilter(CRUDMixin): + + def setUp(self): + self.project = prepare_project() + self.url = reverse(viewname='member_list', args=[self.project.item.id]) + self.url += f'?user={self.project.users[0].id}' + + def test_filter_role_by_user_id(self): + response = self.assert_fetch(self.project.users[0], status.HTTP_200_OK) + self.assertEqual(len(response.data), 1) diff --git a/backend/roles/urls.py b/backend/roles/urls.py index 6354d458..d5a979ac 100644 --- a/backend/roles/urls.py +++ b/backend/roles/urls.py @@ -1,6 +1,6 @@ from django.urls import path -from .views import RoleMappingDetail, RoleMappingList, Roles +from .views import MemberDetail, MemberList, Roles urlpatterns = [ path( @@ -9,13 +9,13 @@ urlpatterns = [ name='roles' ), path( - route='projects//roles', - view=RoleMappingList.as_view(), - name='rolemapping_list' + route='projects//members', + view=MemberList.as_view(), + name='member_list' ), path( - route='projects//roles/', - view=RoleMappingDetail.as_view(), - name='rolemapping_detail' + route='projects//members/', + view=MemberDetail.as_view(), + name='member_detail' ) ] diff --git a/backend/roles/views.py b/backend/roles/views.py index de963771..8b85afc6 100644 --- a/backend/roles/views.py +++ b/backend/roles/views.py @@ -1,13 +1,12 @@ from django.db import IntegrityError -from django.shortcuts import get_object_or_404 +from django_filters.rest_framework import DjangoFilterBackend from rest_framework import generics, status from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response -from api.models import Project from .permissions import IsProjectAdmin from .models import Role, RoleMapping -from .serializers import RoleMappingSerializer, RoleSerializer +from .serializers import MemberSerializer, RoleSerializer from .exceptions import RoleAlreadyAssignedException, RoleConstraintException @@ -18,43 +17,44 @@ class Roles(generics.ListAPIView): queryset = Role.objects.all() -class RoleMappingList(generics.ListCreateAPIView): - serializer_class = RoleMappingSerializer +class MemberList(generics.ListCreateAPIView): + filter_backends = [DjangoFilterBackend] + filterset_fields = ['user'] + queryset = RoleMapping.objects.all() + serializer_class = MemberSerializer pagination_class = None permission_classes = [IsAuthenticated & IsProjectAdmin] - @property - def project(self): - return get_object_or_404(Project, pk=self.kwargs['project_id']) - - def get_queryset(self): - return self.project.role_mappings + def filter_queryset(self, queryset): + queryset = queryset.filter(project=self.kwargs['project_id']) + return super().filter_queryset(queryset) def perform_create(self, serializer): try: - serializer.save(project=self.project) + serializer.save(project_id=self.kwargs['project_id']) except IntegrityError: raise RoleAlreadyAssignedException def delete(self, request, *args, **kwargs): delete_ids = request.data['ids'] - RoleMapping.objects.filter(project=self.project, pk__in=delete_ids)\ + project_id = self.kwargs['project_id'] + RoleMapping.objects.filter(project=project_id, pk__in=delete_ids)\ .exclude(user=self.request.user)\ .delete() return Response(status=status.HTTP_204_NO_CONTENT) -class RoleMappingDetail(generics.RetrieveUpdateAPIView): +class MemberDetail(generics.RetrieveUpdateAPIView): queryset = RoleMapping.objects.all() - serializer_class = RoleMappingSerializer - lookup_url_kwarg = 'rolemapping_id' + serializer_class = MemberSerializer + lookup_url_kwarg = 'member_id' permission_classes = [IsAuthenticated & IsProjectAdmin] def perform_update(self, serializer): project_id = self.kwargs['project_id'] - id = self.kwargs['rolemapping_id'] + member_id = self.kwargs['member_id'] role = serializer.validated_data['role'] - if not RoleMapping.objects.can_update(project_id, id, role.name): + if not RoleMapping.objects.can_update(project_id, member_id, role.name): raise RoleConstraintException try: super().perform_update(serializer)