diff --git a/apps/account/urls.py b/apps/account/urls.py index 5cca63f..8596931 100644 --- a/apps/account/urls.py +++ b/apps/account/urls.py @@ -9,6 +9,7 @@ from apps.geolocation_package.views.region_info import RegionInfoView admin_router = SimpleRouter() admin_router.register(r'users', views.AdminUserViewSet, basename='admin-users') +admin_router.register(r'directory-users', views.AdminUserDirectoryViewSet, basename='admin-directory-users') admin_router.register(r'notifications', views.AdminNotificationViewSet, basename='admin-notifications') # Hide admin viewsets from swagger diff --git a/apps/account/views/user.py b/apps/account/views/user.py index d2d74fd..c5d8e69 100644 --- a/apps/account/views/user.py +++ b/apps/account/views/user.py @@ -715,3 +715,65 @@ class AdminUserViewSet(ModelViewSet): queryset = queryset.order_by('-date_joined') return queryset.distinct() + + +class AdminUserDirectoryViewSet(ModelViewSet): + """ + Separate, dedicated endpoint for accounts/users list page. + Filters users who have an email, are not deleted (deleted_at is null). + """ + serializer_class = AdminUserSerializer + permission_classes = [IsAuthenticated, IsSuperAdminOrReadOnlyForProfessor] + authentication_classes = [TokenAuthentication] + pagination_class = StandardResultsSetPagination + filter_backends = [] + + def get_queryset(self): + # Filter users who have an email and are not soft-deleted + queryset = User.objects.filter(email__isnull=False, deleted_at__isnull=True).exclude(email='') + + # Restrict queryset for professors to only students/clients of their courses + if self.request.user.user_type == 'professor': + queryset = queryset.filter( + Q(user_type='student') | Q(user_type='client'), + participated_courses__course__professors=self.request.user + ) + + # Handle Search + search_query = self.request.query_params.get('search', None) + if search_query: + queryset = queryset.filter( + Q(fullname__icontains=search_query) | + Q(email__icontains=search_query) | + Q(phone_number__icontains=search_query) + ) + + # Handle is_active filter + is_active_param = self.request.query_params.get('is_active', None) + if is_active_param is not None: + if is_active_param.lower() == 'true': + queryset = queryset.filter(is_active=True) + elif is_active_param.lower() == 'false': + queryset = queryset.filter(is_active=False) + + # Handle user type filter + user_type_param = self.request.query_params.get('user_type', None) + if user_type_param: + if user_type_param == 'student': + queryset = queryset.filter(Q(user_type='student') | Q(user_type='client')) + else: + queryset = queryset.filter(user_type=user_type_param) + + # Handle Ordering + ordering_param = self.request.query_params.get('ordering', '-date_joined') + allowed_orderings = [ + 'date_joined', '-date_joined', + 'last_login', '-last_login', + 'fullname', '-fullname' + ] + if ordering_param in allowed_orderings: + queryset = queryset.order_by(ordering_param) + else: + queryset = queryset.order_by('-date_joined') + + return queryset.distinct()