From 777308d4a139dd224cf0047f8784e3acdc7a5ca5 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Tue, 15 Oct 2024 21:25:52 +0300 Subject: [PATCH 01/14] add filters in admin/users --- BackEnd/administration/filters.py | 45 +++++++++++++++++++ BackEnd/administration/serializers.py | 9 +++- .../administration/tests/test_admin_user.py | 2 + BackEnd/administration/views.py | 25 ++++++++++- 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 BackEnd/administration/filters.py diff --git a/BackEnd/administration/filters.py b/BackEnd/administration/filters.py new file mode 100644 index 000000000..54ac0c1c4 --- /dev/null +++ b/BackEnd/administration/filters.py @@ -0,0 +1,45 @@ +from django_filters import filters +from django_filters.rest_framework import FilterSet +from authentication.models import CustomUser +from rest_framework import viewsets + + +class UsersFilter(FilterSet): + id = filters.CharFilter(lookup_expr="icontains") + surname = filters.CharFilter(lookup_expr="icontains") + email = filters.CharFilter(lookup_expr="icontains") + company_name = filters.CharFilter( + field_name="profile__name", lookup_expr="icontains" + ) + status = filters.CharFilter(lookup_expr="icontains") + registration_date = filters.CharFilter(lookup_expr="icontains") + + def is_saved_filter(self, queryset, name, value): + if value: + if self.request.user.is_authenticated: + queryset = queryset.filter(saved_list__user=self.request.user) + else: + queryset = queryset.none() + return queryset + + ordering = filters.OrderingFilter( + fields=( + ("id", "id"), + ("surname", "surname"), + ("email", "email"), + ("company_name", "company_name"), + ("registration_date", "registration_date"), + ("status", "status"), + ) + ) + + class Meta: + model = CustomUser + fields = [ + "id", + "surname", + "email", + "company_name", + "status", + "registration_date", + ] diff --git a/BackEnd/administration/serializers.py b/BackEnd/administration/serializers.py index baf85ea34..da8d8204c 100644 --- a/BackEnd/administration/serializers.py +++ b/BackEnd/administration/serializers.py @@ -51,15 +51,22 @@ def create(self, validated_data): class AdminUserListSerializer(serializers.ModelSerializer): + company_name = serializers.SerializerMethodField() + class Meta: model = CustomUser fields = ( "id", "email", - "name", + "name", # TODO deleted and rename "surname", + "is_active", + "company_name", ) + def get_company_name(self, obj) -> str: + return obj.profile.name if hasattr(obj, "profile") else "" + class AdminUserDetailSerializer(serializers.ModelSerializer): company_name = serializers.SerializerMethodField() diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 21dfc3f1d..6b9d216f4 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -44,6 +44,8 @@ def test_get_users_authenticated(self): "email": "test39@test.com", "name": "Test person 39", "surname": "Test person 39 surname", + "is_active": True, + "company_name": "", } ] self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index e2bf80daa..6641eb4fb 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -28,17 +28,40 @@ from authentication.models import CustomUser from profiles.models import Profile from .permissions import IsStaffUser, IsStaffUserOrReadOnly, IsSuperUser +from django_filters.rest_framework import DjangoFilterBackend as filters +from .filters import UsersFilter class UsersListView(ListAPIView): """ List of users. + Query parameters: + ?sort=id&direction=asc + Filters: + ?company_name= """ permission_classes = [IsStaffUser] pagination_class = ListPagination serializer_class = AdminUserListSerializer - queryset = CustomUser.objects.all().order_by("id") + queryset = CustomUser.objects.all() # .order_by("id") TODO + filter_backends = [ + filters, + ] + filterset_class = UsersFilter + + def get_queryset(self): + queryset = super().get_queryset() + + status = self.request.query_params.get("status", None) + if status: + queryset = queryset.filter(status=status) + + sort = self.request.query_params.get("sort", "name") + direction = self.request.query_params.get("direction", "asc") + if direction == "desc": + sort = f"-{sort}" + return queryset.order_by(sort) class UserDetailView(RetrieveUpdateDestroyAPIView): From 06eddb1769f80e92602163e3db30b55164f9881d Mon Sep 17 00:00:00 2001 From: romanmyko Date: Wed, 16 Oct 2024 20:13:23 +0300 Subject: [PATCH 02/14] filter&sort users v 1.0.2 test json version --- BackEnd/administration/filters.py | 12 ++------- BackEnd/administration/serializers.py | 25 ++++++++++++++++--- .../administration/tests/test_admin_user.py | 9 +++++-- BackEnd/administration/views.py | 3 ++- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/BackEnd/administration/filters.py b/BackEnd/administration/filters.py index 54ac0c1c4..f478f8809 100644 --- a/BackEnd/administration/filters.py +++ b/BackEnd/administration/filters.py @@ -1,7 +1,6 @@ from django_filters import filters from django_filters.rest_framework import FilterSet from authentication.models import CustomUser -from rest_framework import viewsets class UsersFilter(FilterSet): @@ -13,18 +12,10 @@ class UsersFilter(FilterSet): ) status = filters.CharFilter(lookup_expr="icontains") registration_date = filters.CharFilter(lookup_expr="icontains") - - def is_saved_filter(self, queryset, name, value): - if value: - if self.request.user.is_authenticated: - queryset = queryset.filter(saved_list__user=self.request.user) - else: - queryset = queryset.none() - return queryset - ordering = filters.OrderingFilter( fields=( ("id", "id"), + ("name", "name"), ("surname", "surname"), ("email", "email"), ("company_name", "company_name"), @@ -37,6 +28,7 @@ class Meta: model = CustomUser fields = [ "id", + "name", "surname", "email", "company_name", diff --git a/BackEnd/administration/serializers.py b/BackEnd/administration/serializers.py index da8d8204c..b02ed2f27 100644 --- a/BackEnd/administration/serializers.py +++ b/BackEnd/administration/serializers.py @@ -52,20 +52,39 @@ def create(self, validated_data): class AdminUserListSerializer(serializers.ModelSerializer): company_name = serializers.SerializerMethodField() + registration_date = serializers.SerializerMethodField() + status = serializers.SerializerMethodField() class Meta: model = CustomUser fields = ( "id", "email", - "name", # TODO deleted and rename + "name", "surname", - "is_active", + "status", "company_name", + "registration_date", ) def get_company_name(self, obj) -> str: - return obj.profile.name if hasattr(obj, "profile") else "" + return obj.profile.name if hasattr(obj, "profile") else "No profile" + + def get_registration_date(self, obj) -> str: + return ( + obj.profile.created_at if hasattr(obj, "profile") else "No profile" + ) + + def get_status(self, obj) -> dict: + return { + "is_active": obj.is_active, + "is_deleted": obj.profile.is_deleted + if hasattr(obj, "profile") + else False, + "status": obj.profile.status + if hasattr(obj, "profile") + else "pending", + } class AdminUserDetailSerializer(serializers.ModelSerializer): diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 6b9d216f4..6899044a5 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -44,8 +44,13 @@ def test_get_users_authenticated(self): "email": "test39@test.com", "name": "Test person 39", "surname": "Test person 39 surname", - "is_active": True, - "company_name": "", + "status": { + "is_active": True, + "is_deleted": False, + "status": "pending", + }, + "company_name": "No profile", + "registration_date": "No profile", } ] self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 6641eb4fb..743e127a8 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -28,6 +28,7 @@ from authentication.models import CustomUser from profiles.models import Profile from .permissions import IsStaffUser, IsStaffUserOrReadOnly, IsSuperUser + from django_filters.rest_framework import DjangoFilterBackend as filters from .filters import UsersFilter @@ -44,7 +45,7 @@ class UsersListView(ListAPIView): permission_classes = [IsStaffUser] pagination_class = ListPagination serializer_class = AdminUserListSerializer - queryset = CustomUser.objects.all() # .order_by("id") TODO + queryset = CustomUser.objects.all().order_by("id") filter_backends = [ filters, ] From 0d7c713f2557a71ee6403d6f9e828f5d58f0aee5 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Wed, 16 Oct 2024 20:28:45 +0300 Subject: [PATCH 03/14] filter.py deleted classes v 1.0.2 test json version --- BackEnd/administration/filters.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/BackEnd/administration/filters.py b/BackEnd/administration/filters.py index f478f8809..7ecfd6a3e 100644 --- a/BackEnd/administration/filters.py +++ b/BackEnd/administration/filters.py @@ -1,6 +1,5 @@ from django_filters import filters from django_filters.rest_framework import FilterSet -from authentication.models import CustomUser class UsersFilter(FilterSet): @@ -23,15 +22,3 @@ class UsersFilter(FilterSet): ("status", "status"), ) ) - - class Meta: - model = CustomUser - fields = [ - "id", - "name", - "surname", - "email", - "company_name", - "status", - "registration_date", - ] From 9602b201de8cfe9baab8d46258c153aaa540d337 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Thu, 17 Oct 2024 17:13:39 +0300 Subject: [PATCH 04/14] format staus in JSON v 1.0.3 --- BackEnd/administration/serializers.py | 14 ++++++-------- BackEnd/administration/tests/test_admin_user.py | 6 +++--- BackEnd/administration/views.py | 6 ++---- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/BackEnd/administration/serializers.py b/BackEnd/administration/serializers.py index b02ed2f27..9070858bf 100644 --- a/BackEnd/administration/serializers.py +++ b/BackEnd/administration/serializers.py @@ -76,15 +76,13 @@ def get_registration_date(self, obj) -> str: ) def get_status(self, obj) -> dict: - return { - "is_active": obj.is_active, - "is_deleted": obj.profile.is_deleted - if hasattr(obj, "profile") - else False, - "status": obj.profile.status - if hasattr(obj, "profile") - else "pending", + has_profile = hasattr(obj, "profile") + data = { + "is_active": obj.is_active if has_profile else False, + "is_staff": obj.is_staff if has_profile else False, + "is_superuser": obj.is_superuser if has_profile else False, } + return data class AdminUserDetailSerializer(serializers.ModelSerializer): diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 6899044a5..e76410533 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -45,9 +45,9 @@ def test_get_users_authenticated(self): "name": "Test person 39", "surname": "Test person 39 surname", "status": { - "is_active": True, - "is_deleted": False, - "status": "pending", + "is_active": False, + "is_staff": False, + "is_superuser": False, }, "company_name": "No profile", "registration_date": "No profile", diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 743e127a8..1a850a0e1 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -45,10 +45,8 @@ class UsersListView(ListAPIView): permission_classes = [IsStaffUser] pagination_class = ListPagination serializer_class = AdminUserListSerializer - queryset = CustomUser.objects.all().order_by("id") - filter_backends = [ - filters, - ] + queryset = CustomUser.objects.all() + filter_backends = [filters] filterset_class = UsersFilter def get_queryset(self): From a40f8cbf2753630097b82c22f7f1e1fd0bd3bae7 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Thu, 17 Oct 2024 21:12:12 +0300 Subject: [PATCH 05/14] test desc/asc v 1.0.1 --- BackEnd/administration/factories.py | 1 + .../administration/tests/test_admin_user.py | 96 ++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/BackEnd/administration/factories.py b/BackEnd/administration/factories.py index f1cd4e1d6..6d83e807e 100644 --- a/BackEnd/administration/factories.py +++ b/BackEnd/administration/factories.py @@ -15,6 +15,7 @@ class Meta: is_active = True is_staff = True + is_superuser = False class AdminProfileFactory(factory.django.DjangoModelFactory): diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index e76410533..9ac2c3812 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -23,6 +23,79 @@ def test_get_user_id_not_staff(self): self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code) +class TestAdminUsersListAPITests(APITestCase): + def setUp(self): + self.users = AdminUserFactory.create_batch(2) + self.user = self.users[0] + + def test_get_users_sort_desc(self): + self.client.force_authenticate(self.user) + response = self.client.get(path="/api/admin/users/?sort=id&direction=desc") + data = [ + { + "id": 47, + "email": "test47@test.com", + "name": "Test person 47", + "surname": "Test person 47 surname", + "status": { + "is_active": False, + "is_staff": False, + "is_superuser": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + }, + { + "id": 46, + "email": "test46@test.com", + "name": "Test person 46", + "surname": "Test person 46 surname", + "status": { + "is_active": False, + "is_staff": False, + "is_superuser": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + }, + ] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(data, response.json()) + + def test_get_users_sort_asc(self): + self.client.force_authenticate(self.user) + response = self.client.get(path="/api/admin/users/?sort=id&direction=asc") + data = [ + { + "id": 44, + "email": "test44@test.com", + "name": "Test person 44", + "surname": "Test person 44 surname", + "status": { + "is_active": False, + "is_staff": False, + "is_superuser": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + }, + { + "id": 45, + "email": "test45@test.com", + "name": "Test person 45", + "surname": "Test person 45 surname", + "status": { + "is_active": False, + "is_staff": False, + "is_superuser": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + }, + ] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(data, response.json()) + class TestAdminUsersAPITests(APITestCase): def setUp(self): self.user = AdminUserFactory() @@ -55,7 +128,28 @@ def test_get_users_authenticated(self): ] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - + + def test_get_users_filter(self): + self.client.force_authenticate(self.user) + response = self.client.get(path="/api/admin/users/?sort=id&direction=asc") + data = [ + { + "id": 40, + "email": "test40@test.com", + "name": "Test person 40", + "surname": "Test person 40 surname", + "status": { + "is_active": False, + "is_staff": False, + "is_superuser": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + } + ] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(data, response.json()) + def test_get_user_id_authenticated(self): self.client.force_authenticate(self.user) response = self.client.get(path=f"/api/admin/users/{self.user.id}/") From d33db1075013128eea664b45c4a7239b11e7c7b4 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Fri, 18 Oct 2024 15:56:52 +0300 Subject: [PATCH 06/14] add is deleted user status in json --- BackEnd/administration/serializers.py | 8 +-- .../administration/tests/test_admin_user.py | 49 ++++++++++++------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/BackEnd/administration/serializers.py b/BackEnd/administration/serializers.py index 9070858bf..a2a3a0ebd 100644 --- a/BackEnd/administration/serializers.py +++ b/BackEnd/administration/serializers.py @@ -76,11 +76,11 @@ def get_registration_date(self, obj) -> str: ) def get_status(self, obj) -> dict: - has_profile = hasattr(obj, "profile") data = { - "is_active": obj.is_active if has_profile else False, - "is_staff": obj.is_staff if has_profile else False, - "is_superuser": obj.is_superuser if has_profile else False, + "is_active": obj.is_active, + "is_staff": obj.is_staff, + "is_superuser": obj.is_superuser, + "is_deleted": obj.email.startswith("is_deleted_"), } return data diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 9ac2c3812..974f1abea 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -30,7 +30,9 @@ def setUp(self): def test_get_users_sort_desc(self): self.client.force_authenticate(self.user) - response = self.client.get(path="/api/admin/users/?sort=id&direction=desc") + response = self.client.get( + path="/api/admin/users/?sort=id&direction=desc" + ) data = [ { "id": 47, @@ -38,9 +40,10 @@ def test_get_users_sort_desc(self): "name": "Test person 47", "surname": "Test person 47 surname", "status": { - "is_active": False, - "is_staff": False, + "is_active": True, + "is_staff": True, "is_superuser": False, + "is_deleted": False, }, "company_name": "No profile", "registration_date": "No profile", @@ -51,9 +54,10 @@ def test_get_users_sort_desc(self): "name": "Test person 46", "surname": "Test person 46 surname", "status": { - "is_active": False, - "is_staff": False, + "is_active": True, + "is_staff": True, "is_superuser": False, + "is_deleted": False, }, "company_name": "No profile", "registration_date": "No profile", @@ -61,10 +65,12 @@ def test_get_users_sort_desc(self): ] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - + def test_get_users_sort_asc(self): self.client.force_authenticate(self.user) - response = self.client.get(path="/api/admin/users/?sort=id&direction=asc") + response = self.client.get( + path="/api/admin/users/?sort=id&direction=asc" + ) data = [ { "id": 44, @@ -72,9 +78,10 @@ def test_get_users_sort_asc(self): "name": "Test person 44", "surname": "Test person 44 surname", "status": { - "is_active": False, - "is_staff": False, + "is_active": True, + "is_staff": True, "is_superuser": False, + "is_deleted": False, }, "company_name": "No profile", "registration_date": "No profile", @@ -85,9 +92,10 @@ def test_get_users_sort_asc(self): "name": "Test person 45", "surname": "Test person 45 surname", "status": { - "is_active": False, - "is_staff": False, + "is_active": True, + "is_staff": True, "is_superuser": False, + "is_deleted": False, }, "company_name": "No profile", "registration_date": "No profile", @@ -96,6 +104,7 @@ def test_get_users_sort_asc(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) + class TestAdminUsersAPITests(APITestCase): def setUp(self): self.user = AdminUserFactory() @@ -118,9 +127,10 @@ def test_get_users_authenticated(self): "name": "Test person 39", "surname": "Test person 39 surname", "status": { - "is_active": False, - "is_staff": False, + "is_active": True, + "is_staff": True, "is_superuser": False, + "is_deleted": False, }, "company_name": "No profile", "registration_date": "No profile", @@ -128,10 +138,12 @@ def test_get_users_authenticated(self): ] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - + def test_get_users_filter(self): self.client.force_authenticate(self.user) - response = self.client.get(path="/api/admin/users/?sort=id&direction=asc") + response = self.client.get( + path="/api/admin/users/?sort=id&direction=asc" + ) data = [ { "id": 40, @@ -139,9 +151,10 @@ def test_get_users_filter(self): "name": "Test person 40", "surname": "Test person 40 surname", "status": { - "is_active": False, - "is_staff": False, + "is_active": True, + "is_staff": True, "is_superuser": False, + "is_deleted": False, }, "company_name": "No profile", "registration_date": "No profile", @@ -149,7 +162,7 @@ def test_get_users_filter(self): ] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - + def test_get_user_id_authenticated(self): self.client.force_authenticate(self.user) response = self.client.get(path=f"/api/admin/users/{self.user.id}/") From 653c036b7fc8d265520a4e0066e9165284ce88c6 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Fri, 18 Oct 2024 18:03:26 +0300 Subject: [PATCH 07/14] add filter is deleted --- BackEnd/administration/filters.py | 32 ++++++++++++++++++++++++++----- BackEnd/administration/views.py | 15 ++++++++++++--- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/BackEnd/administration/filters.py b/BackEnd/administration/filters.py index 7ecfd6a3e..cb8e3ece5 100644 --- a/BackEnd/administration/filters.py +++ b/BackEnd/administration/filters.py @@ -3,22 +3,44 @@ class UsersFilter(FilterSet): + """ + Filters + /?id= ,/?name=, /?surname=, /?email= , /?is_active= , /?is_staff=, + /?is_superuser=, /?is_deleted=, /?company_name=, /?egistration_date=, + """ + id = filters.CharFilter(lookup_expr="icontains") surname = filters.CharFilter(lookup_expr="icontains") email = filters.CharFilter(lookup_expr="icontains") + is_active = filters.CharFilter(lookup_expr="icontains") + is_staff = filters.CharFilter(lookup_expr="icontains") + is_superuser = filters.CharFilter(lookup_expr="icontains") + is_deleted = filters.BooleanFilter(method="filter_is_deleted") company_name = filters.CharFilter( field_name="profile__name", lookup_expr="icontains" ) - status = filters.CharFilter(lookup_expr="icontains") - registration_date = filters.CharFilter(lookup_expr="icontains") + registration_date = filters.CharFilter( + field_name="profile__created_at", lookup_expr="icontains" + ) + + def filter_is_deleted(self, queryset, name, value): + if value: + queryset = queryset.filter(email__startswith="is_deleted_") + else: + queryset = queryset.exclude(email__startswith="is_deleted_") + return queryset + ordering = filters.OrderingFilter( fields=( ("id", "id"), ("name", "name"), ("surname", "surname"), ("email", "email"), - ("company_name", "company_name"), - ("registration_date", "registration_date"), - ("status", "status"), + ("is_active", "is_active"), + ("is_staff", "is_staff"), + ("is_superuser", "is_superuser"), + ("profile__name", "company_name"), + ("profile__created_at", "registration_date"), + ("email", "is_deleted"), ) ) diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 1a850a0e1..80b743119 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -37,9 +37,9 @@ class UsersListView(ListAPIView): """ List of users. Query parameters: - ?sort=id&direction=asc + /?sort=id&direction=asc or /?sort=id&direction=desc Filters: - ?company_name= + /?company_name= ,/?status=active/inactive/staff/superuser/deleted """ permission_classes = [IsStaffUser] @@ -54,7 +54,16 @@ def get_queryset(self): status = self.request.query_params.get("status", None) if status: - queryset = queryset.filter(status=status) + if status == "active": + queryset = queryset.filter(is_active=True) + elif status == "inactive": + queryset = queryset.filter(is_active=False) + elif status == "staff": + queryset = queryset.filter(is_staff=True) + elif status == "superuser": + queryset = queryset.filter(is_superuser=True) + elif status == "deleted": + queryset = queryset.filter(email__startswith="is_deleted_") sort = self.request.query_params.get("sort", "name") direction = self.request.query_params.get("direction", "asc") From 6b472066a167f9b67704a16f03e82715146ec600 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Fri, 18 Oct 2024 21:11:54 +0300 Subject: [PATCH 08/14] test status and filter in admin users list v 1.0.2 --- .../administration/tests/test_admin_user.py | 99 ++++++++++++++++--- 1 file changed, 88 insertions(+), 11 deletions(-) diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 974f1abea..7a9f97c3f 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -23,7 +23,7 @@ def test_get_user_id_not_staff(self): self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code) -class TestAdminUsersListAPITests(APITestCase): +class TestAdminUsersSortFilterAPITests(APITestCase): def setUp(self): self.users = AdminUserFactory.create_batch(2) self.user = self.users[0] @@ -35,10 +35,10 @@ def test_get_users_sort_desc(self): ) data = [ { - "id": 47, - "email": "test47@test.com", - "name": "Test person 47", - "surname": "Test person 47 surname", + "id": 49, + "email": "test49@test.com", + "name": "Test person 49", + "surname": "Test person 49 surname", "status": { "is_active": True, "is_staff": True, @@ -48,6 +48,30 @@ def test_get_users_sort_desc(self): "company_name": "No profile", "registration_date": "No profile", }, + { + "id": 48, + "email": "test48@test.com", + "name": "Test person 48", + "surname": "Test person 48 surname", + "status": { + "is_active": True, + "is_staff": True, + "is_superuser": False, + "is_deleted": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + }, + ] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(data, response.json()) + + def test_get_users_sort_asc(self): + self.client.force_authenticate(self.user) + response = self.client.get( + path="/api/admin/users/?sort=id&direction=asc" + ) + data = [ { "id": 46, "email": "test46@test.com", @@ -62,14 +86,28 @@ def test_get_users_sort_desc(self): "company_name": "No profile", "registration_date": "No profile", }, + { + "id": 47, + "email": "test47@test.com", + "name": "Test person 47", + "surname": "Test person 47 surname", + "status": { + "is_active": True, + "is_staff": True, + "is_superuser": False, + "is_deleted": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + }, ] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - def test_get_users_sort_asc(self): + def test_get_users_filter_id_name_surname(self): self.client.force_authenticate(self.user) response = self.client.get( - path="/api/admin/users/?sort=id&direction=asc" + path="/api/admin/users/?id=44&name=44&surname=44" ) data = [ { @@ -86,11 +124,41 @@ def test_get_users_sort_asc(self): "company_name": "No profile", "registration_date": "No profile", }, + ] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(data, response.json()) + + +class TestAdminUsersStatusAPITests(APITestCase): + def setUp(self): + self.users = AdminUserFactory.create_batch(2) + self.user = self.users[0] + + def test_get_users_filter_status_active_staff(self): + self.client.force_authenticate(self.user) + response = self.client.get( + path="/api/admin/users/?status=active&status=staff" + ) + data = [ + { + "id": 50, + "email": "test50@test.com", + "name": "Test person 50", + "surname": "Test person 50 surname", + "status": { + "is_active": True, + "is_staff": True, + "is_superuser": False, + "is_deleted": False, + }, + "company_name": "No profile", + "registration_date": "No profile", + }, { - "id": 45, - "email": "test45@test.com", - "name": "Test person 45", - "surname": "Test person 45 surname", + "id": 51, + "email": "test51@test.com", + "name": "Test person 51", + "surname": "Test person 51 surname", "status": { "is_active": True, "is_staff": True, @@ -104,6 +172,15 @@ def test_get_users_sort_asc(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) + def test_get_users_filter_status_superuser_staff(self): + self.client.force_authenticate(self.user) + response = self.client.get( + path="/api/admin/users/?status=superuser&status=deleted&status=inactive" + ) + data = [] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(data, response.json()) + class TestAdminUsersAPITests(APITestCase): def setUp(self): From 5690521c453108c2c2c96ef9773004c2426af11b Mon Sep 17 00:00:00 2001 From: romanmyko Date: Sun, 20 Oct 2024 20:12:35 +0300 Subject: [PATCH 09/14] none in company name and date , correct filters and test --- BackEnd/administration/filters.py | 8 ++--- BackEnd/administration/serializers.py | 6 ++-- .../administration/tests/test_admin_user.py | 36 +++++++++---------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/BackEnd/administration/filters.py b/BackEnd/administration/filters.py index cb8e3ece5..da89224de 100644 --- a/BackEnd/administration/filters.py +++ b/BackEnd/administration/filters.py @@ -6,7 +6,9 @@ class UsersFilter(FilterSet): """ Filters /?id= ,/?name=, /?surname=, /?email= , /?is_active= , /?is_staff=, - /?is_superuser=, /?is_deleted=, /?company_name=, /?egistration_date=, + /?is_superuser=, /?is_deleted=True or False, /?company_name=, /?registration_date=, + Ordering sample + /?ordering=id asc or /?ordering=-id desc """ id = filters.CharFilter(lookup_expr="icontains") @@ -26,8 +28,6 @@ class UsersFilter(FilterSet): def filter_is_deleted(self, queryset, name, value): if value: queryset = queryset.filter(email__startswith="is_deleted_") - else: - queryset = queryset.exclude(email__startswith="is_deleted_") return queryset ordering = filters.OrderingFilter( @@ -39,8 +39,8 @@ def filter_is_deleted(self, queryset, name, value): ("is_active", "is_active"), ("is_staff", "is_staff"), ("is_superuser", "is_superuser"), + ("is_deleted", "is_deleted"), ("profile__name", "company_name"), ("profile__created_at", "registration_date"), - ("email", "is_deleted"), ) ) diff --git a/BackEnd/administration/serializers.py b/BackEnd/administration/serializers.py index a2a3a0ebd..98ef080c6 100644 --- a/BackEnd/administration/serializers.py +++ b/BackEnd/administration/serializers.py @@ -68,12 +68,10 @@ class Meta: ) def get_company_name(self, obj) -> str: - return obj.profile.name if hasattr(obj, "profile") else "No profile" + return obj.profile.name if hasattr(obj, "profile") else None def get_registration_date(self, obj) -> str: - return ( - obj.profile.created_at if hasattr(obj, "profile") else "No profile" - ) + return obj.profile.created_at if hasattr(obj, "profile") else None def get_status(self, obj) -> dict: data = { diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 7a9f97c3f..3426b0497 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -45,8 +45,8 @@ def test_get_users_sort_desc(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, }, { "id": 48, @@ -59,8 +59,8 @@ def test_get_users_sort_desc(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, }, ] self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -83,8 +83,8 @@ def test_get_users_sort_asc(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, }, { "id": 47, @@ -97,8 +97,8 @@ def test_get_users_sort_asc(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, }, ] self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -121,8 +121,8 @@ def test_get_users_filter_id_name_surname(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, }, ] self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -151,8 +151,8 @@ def test_get_users_filter_status_active_staff(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, }, { "id": 51, @@ -165,8 +165,8 @@ def test_get_users_filter_status_active_staff(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, }, ] self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -209,8 +209,8 @@ def test_get_users_authenticated(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, } ] self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -233,8 +233,8 @@ def test_get_users_filter(self): "is_superuser": False, "is_deleted": False, }, - "company_name": "No profile", - "registration_date": "No profile", + "company_name": None, + "registration_date": None, } ] self.assertEqual(response.status_code, status.HTTP_200_OK) From 3384f643d643624c58468ad763d2dfd563488bbc Mon Sep 17 00:00:00 2001 From: romanmyko Date: Mon, 21 Oct 2024 11:14:28 +0300 Subject: [PATCH 10/14] deleted in views def queryset and correct test v1.0.3 --- BackEnd/administration/filters.py | 2 +- .../administration/tests/test_admin_user.py | 26 ++++++--------- BackEnd/administration/views.py | 32 +++---------------- 3 files changed, 15 insertions(+), 45 deletions(-) diff --git a/BackEnd/administration/filters.py b/BackEnd/administration/filters.py index da89224de..5827449cd 100644 --- a/BackEnd/administration/filters.py +++ b/BackEnd/administration/filters.py @@ -5,7 +5,7 @@ class UsersFilter(FilterSet): """ Filters - /?id= ,/?name=, /?surname=, /?email= , /?is_active= , /?is_staff=, + /?id= , /?surname=, /?email= , /?is_active= , /?is_staff=, /?is_superuser=, /?is_deleted=True or False, /?company_name=, /?registration_date=, Ordering sample /?ordering=id asc or /?ordering=-id desc diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 3426b0497..59e028e51 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -23,16 +23,14 @@ def test_get_user_id_not_staff(self): self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code) -class TestAdminUsersSortFilterAPITests(APITestCase): +class TestAdminUsersOrderingFilterAPITests(APITestCase): def setUp(self): self.users = AdminUserFactory.create_batch(2) self.user = self.users[0] - def test_get_users_sort_desc(self): + def test_get_users_ordering_desc(self): self.client.force_authenticate(self.user) - response = self.client.get( - path="/api/admin/users/?sort=id&direction=desc" - ) + response = self.client.get(path="/api/admin/users/?ordering=-id") data = [ { "id": 49, @@ -66,11 +64,9 @@ def test_get_users_sort_desc(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - def test_get_users_sort_asc(self): + def test_get_users_ordering_asc(self): self.client.force_authenticate(self.user) - response = self.client.get( - path="/api/admin/users/?sort=id&direction=asc" - ) + response = self.client.get(path="/api/admin/users/?ordering=id") data = [ { "id": 46, @@ -104,11 +100,9 @@ def test_get_users_sort_asc(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - def test_get_users_filter_id_name_surname(self): + def test_get_users_filter_id_surname(self): self.client.force_authenticate(self.user) - response = self.client.get( - path="/api/admin/users/?id=44&name=44&surname=44" - ) + response = self.client.get(path="/api/admin/users/?id=44&surname=44") data = [ { "id": 44, @@ -137,7 +131,7 @@ def setUp(self): def test_get_users_filter_status_active_staff(self): self.client.force_authenticate(self.user) response = self.client.get( - path="/api/admin/users/?status=active&status=staff" + path="/api/admin/users/?is_active=True&is_staff=True" ) data = [ { @@ -172,10 +166,10 @@ def test_get_users_filter_status_active_staff(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(data, response.json()) - def test_get_users_filter_status_superuser_staff(self): + def test_get_users_filter_status_superuser_staff_active(self): self.client.force_authenticate(self.user) response = self.client.get( - path="/api/admin/users/?status=superuser&status=deleted&status=inactive" + path="/api/admin/users/?is_superuser=True&is_deleted=True&is_active=False" ) data = [] self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 80b743119..8c0695ff9 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -29,48 +29,24 @@ from profiles.models import Profile from .permissions import IsStaffUser, IsStaffUserOrReadOnly, IsSuperUser -from django_filters.rest_framework import DjangoFilterBackend as filters +from django_filters.rest_framework import DjangoFilterBackend from .filters import UsersFilter class UsersListView(ListAPIView): """ List of users. - Query parameters: - /?sort=id&direction=asc or /?sort=id&direction=desc - Filters: - /?company_name= ,/?status=active/inactive/staff/superuser/deleted + - Query parameters + - Filters: DjangoFilterBackend """ permission_classes = [IsStaffUser] pagination_class = ListPagination serializer_class = AdminUserListSerializer queryset = CustomUser.objects.all() - filter_backends = [filters] + filter_backends = [DjangoFilterBackend] filterset_class = UsersFilter - def get_queryset(self): - queryset = super().get_queryset() - - status = self.request.query_params.get("status", None) - if status: - if status == "active": - queryset = queryset.filter(is_active=True) - elif status == "inactive": - queryset = queryset.filter(is_active=False) - elif status == "staff": - queryset = queryset.filter(is_staff=True) - elif status == "superuser": - queryset = queryset.filter(is_superuser=True) - elif status == "deleted": - queryset = queryset.filter(email__startswith="is_deleted_") - - sort = self.request.query_params.get("sort", "name") - direction = self.request.query_params.get("direction", "asc") - if direction == "desc": - sort = f"-{sort}" - return queryset.order_by(sort) - class UserDetailView(RetrieveUpdateDestroyAPIView): """ From c6491cf4a3f88505167dfa257085dba9f9d38d10 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Mon, 21 Oct 2024 15:07:05 +0300 Subject: [PATCH 11/14] correct test v1.0.4 --- BackEnd/administration/tests/test_admin_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 59e028e51..62249050e 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -213,7 +213,7 @@ def test_get_users_authenticated(self): def test_get_users_filter(self): self.client.force_authenticate(self.user) response = self.client.get( - path="/api/admin/users/?sort=id&direction=asc" + path="/api/admin/users/?ordering=id" ) data = [ { From 2d27e9e38e9b53d06feecbc370c9c9c6acd879dc Mon Sep 17 00:00:00 2001 From: romanmyko Date: Mon, 21 Oct 2024 15:12:53 +0300 Subject: [PATCH 12/14] correct test v1.0.5 --- BackEnd/administration/tests/test_admin_user.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 62249050e..6a3f9471d 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -212,9 +212,7 @@ def test_get_users_authenticated(self): def test_get_users_filter(self): self.client.force_authenticate(self.user) - response = self.client.get( - path="/api/admin/users/?ordering=id" - ) + response = self.client.get(path="/api/admin/users/?ordering=id") data = [ { "id": 40, From 8426692b9eec7b479dc790e55b35ede9c433d32e Mon Sep 17 00:00:00 2001 From: romanmyko Date: Mon, 21 Oct 2024 19:52:28 +0300 Subject: [PATCH 13/14] correct test v1.1.1 --- BackEnd/administration/factories.py | 2 + .../administration/tests/test_admin_user.py | 84 ++++++++++--------- BackEnd/administration/views.py | 4 +- 3 files changed, 49 insertions(+), 41 deletions(-) diff --git a/BackEnd/administration/factories.py b/BackEnd/administration/factories.py index 6d83e807e..251ec104b 100644 --- a/BackEnd/administration/factories.py +++ b/BackEnd/administration/factories.py @@ -7,7 +7,9 @@ class AdminUserFactory(factory.django.DjangoModelFactory): class Meta: model = CustomUser + django_get_or_create = ("email",) + id = factory.Sequence(lambda n: n + 1) email = factory.Sequence(lambda n: f"test{n + 1}@test.com") name = factory.Sequence(lambda n: f"Test person {n + 1}") surname = factory.Sequence(lambda n: f"Test person {n + 1} surname") diff --git a/BackEnd/administration/tests/test_admin_user.py b/BackEnd/administration/tests/test_admin_user.py index 6a3f9471d..df94a5485 100644 --- a/BackEnd/administration/tests/test_admin_user.py +++ b/BackEnd/administration/tests/test_admin_user.py @@ -26,6 +26,7 @@ def test_get_user_id_not_staff(self): class TestAdminUsersOrderingFilterAPITests(APITestCase): def setUp(self): self.users = AdminUserFactory.create_batch(2) + AdminUserFactory.reset_sequence(1) self.user = self.users[0] def test_get_users_ordering_desc(self): @@ -33,10 +34,10 @@ def test_get_users_ordering_desc(self): response = self.client.get(path="/api/admin/users/?ordering=-id") data = [ { - "id": 49, - "email": "test49@test.com", - "name": "Test person 49", - "surname": "Test person 49 surname", + "id": 3, + "email": "test3@test.com", + "name": "Test person 3", + "surname": "Test person 3 surname", "status": { "is_active": True, "is_staff": True, @@ -47,10 +48,10 @@ def test_get_users_ordering_desc(self): "registration_date": None, }, { - "id": 48, - "email": "test48@test.com", - "name": "Test person 48", - "surname": "Test person 48 surname", + "id": 2, + "email": "test2@test.com", + "name": "Test person 2", + "surname": "Test person 2 surname", "status": { "is_active": True, "is_staff": True, @@ -69,10 +70,10 @@ def test_get_users_ordering_asc(self): response = self.client.get(path="/api/admin/users/?ordering=id") data = [ { - "id": 46, - "email": "test46@test.com", - "name": "Test person 46", - "surname": "Test person 46 surname", + "id": 2, + "email": "test2@test.com", + "name": "Test person 2", + "surname": "Test person 2 surname", "status": { "is_active": True, "is_staff": True, @@ -83,10 +84,10 @@ def test_get_users_ordering_asc(self): "registration_date": None, }, { - "id": 47, - "email": "test47@test.com", - "name": "Test person 47", - "surname": "Test person 47 surname", + "id": 3, + "email": "test3@test.com", + "name": "Test person 3", + "surname": "Test person 3 surname", "status": { "is_active": True, "is_staff": True, @@ -102,13 +103,13 @@ def test_get_users_ordering_asc(self): def test_get_users_filter_id_surname(self): self.client.force_authenticate(self.user) - response = self.client.get(path="/api/admin/users/?id=44&surname=44") + response = self.client.get(path="/api/admin/users/?id=5&surname=5") data = [ { - "id": 44, - "email": "test44@test.com", - "name": "Test person 44", - "surname": "Test person 44 surname", + "id": 5, + "email": "test5@test.com", + "name": "Test person 5", + "surname": "Test person 5 surname", "status": { "is_active": True, "is_staff": True, @@ -126,6 +127,7 @@ def test_get_users_filter_id_surname(self): class TestAdminUsersStatusAPITests(APITestCase): def setUp(self): self.users = AdminUserFactory.create_batch(2) + AdminUserFactory.reset_sequence(1) self.user = self.users[0] def test_get_users_filter_status_active_staff(self): @@ -135,10 +137,10 @@ def test_get_users_filter_status_active_staff(self): ) data = [ { - "id": 50, - "email": "test50@test.com", - "name": "Test person 50", - "surname": "Test person 50 surname", + "id": 2, + "email": "test2@test.com", + "name": "Test person 2", + "surname": "Test person 2 surname", "status": { "is_active": True, "is_staff": True, @@ -149,10 +151,10 @@ def test_get_users_filter_status_active_staff(self): "registration_date": None, }, { - "id": 51, - "email": "test51@test.com", - "name": "Test person 51", - "surname": "Test person 51 surname", + "id": 3, + "email": "test3@test.com", + "name": "Test person 3", + "surname": "Test person 3 surname", "status": { "is_active": True, "is_staff": True, @@ -179,6 +181,7 @@ def test_get_users_filter_status_superuser_staff_active(self): class TestAdminUsersAPITests(APITestCase): def setUp(self): self.user = AdminUserFactory() + AdminUserFactory.reset_sequence(1) def test_get_users_not_authorized(self): response = self.client.get(path="/api/admin/users/?page=1&page_size=1") @@ -193,10 +196,10 @@ def test_get_users_authenticated(self): response = self.client.get(path="/api/admin/users/") data = [ { - "id": 39, - "email": "test39@test.com", - "name": "Test person 39", - "surname": "Test person 39 surname", + "id": 2, + "email": "test2@test.com", + "name": "Test person 2", + "surname": "Test person 2 surname", "status": { "is_active": True, "is_staff": True, @@ -215,10 +218,10 @@ def test_get_users_filter(self): response = self.client.get(path="/api/admin/users/?ordering=id") data = [ { - "id": 40, - "email": "test40@test.com", - "name": "Test person 40", - "surname": "Test person 40 surname", + "id": 2, + "email": "test2@test.com", + "name": "Test person 2", + "surname": "Test person 2 surname", "status": { "is_active": True, "is_staff": True, @@ -235,11 +238,12 @@ def test_get_users_filter(self): def test_get_user_id_authenticated(self): self.client.force_authenticate(self.user) response = self.client.get(path=f"/api/admin/users/{self.user.id}/") + AdminUserFactory.reset_sequence(1) data = { - "name": "Test person 37", - "surname": "Test person 37 surname", - "email": "test37@test.com", + "name": f"Test person {self.user.id}", + "surname": f"Test person {self.user.id} surname", + "email": f"test{self.user.id}@test.com", "is_active": True, "is_staff": True, "is_superuser": False, diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 8c0695ff9..93af64777 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -43,10 +43,12 @@ class UsersListView(ListAPIView): permission_classes = [IsStaffUser] pagination_class = ListPagination serializer_class = AdminUserListSerializer - queryset = CustomUser.objects.all() filter_backends = [DjangoFilterBackend] filterset_class = UsersFilter + def get_queryset(self): + return CustomUser.objects.select_related("profile") + class UserDetailView(RetrieveUpdateDestroyAPIView): """ From 1286c2573426f6a252412aa8fbe7f22f07ba9a49 Mon Sep 17 00:00:00 2001 From: romanmyko Date: Mon, 21 Oct 2024 21:35:19 +0300 Subject: [PATCH 14/14] format docstring --- BackEnd/administration/views.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 93af64777..3d100d5f6 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -35,9 +35,19 @@ class UsersListView(ListAPIView): """ - List of users. - - Query parameters - - Filters: DjangoFilterBackend + View to list users with optional filtering and ordering. + + ### Query Parameters: + - **id** / **surname** / **email** / **is_active** / **is_staff** / **is_superuser** / **is_deleted** + - **company_name** / **registration_date** + + ### Ordering: + - Use the `ordering` parameter to sort the results. + - Example: `/users/?ordering=id` (ascending by ID) or `/users/?ordering=-id` (descending by ID). + + ### Filters: + - Filters are applied using `DjangoFilterBackend`. All the above query parameters are supported for filtering. + **Without is_deleted** """ permission_classes = [IsStaffUser]