Skip to content

Commit

Permalink
feat: filter and sort learner by name/email
Browse files Browse the repository at this point in the history
fix: pagination
  • Loading branch information
marlonkeating committed Nov 13, 2024
1 parent ad4d01c commit 0f35b9c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Unreleased
----------
* nothing unreleased

[4.32.1]
--------
* feat: filter and sort learner by name/email

[4.32.0]
--------
* feat: create DefaultEnterpriseEnrollmentRealization objects in bulk enrollment API, when applicable.
Expand Down
2 changes: 1 addition & 1 deletion enterprise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Your project description goes here.
"""

__version__ = "4.32.0"
__version__ = "4.32.1"
17 changes: 16 additions & 1 deletion enterprise/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from rest_framework.exceptions import ValidationError

from django.contrib import auth
from django.db.models import Q

from enterprise.models import EnterpriseCustomer, EnterpriseCustomerUser, SystemWideEnterpriseUserRoleAssignment

Expand Down Expand Up @@ -100,6 +101,19 @@ def _filter_by_user_attributes(self, request, queryset):

return queryset

def _filter_by_username_or_email(self, request, queryset):
"""
Filter queryset by email or username using the single 'username_or_email' query parameter
"""
username_or_email = request.query_params.get('username_or_email', None)

if username_or_email:
users = User.objects.filter(Q(username__icontains=username_or_email) | Q(email=username_or_email)) \

Check warning on line 111 in enterprise/api/filters.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/filters.py#L111

Added line #L111 was not covered by tests
.values_list('id', flat=True)
return queryset.filter(user_id__in=users)

Check warning on line 113 in enterprise/api/filters.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/filters.py#L113

Added line #L113 was not covered by tests

return queryset

def _filter_by_enterprise_attributes(self, request, queryset):
"""
Filter queryset by enterprise_customer_uuid or enterprise role.
Expand Down Expand Up @@ -133,7 +147,7 @@ def _filter_by_enterprise_attributes(self, request, queryset):

def filter_queryset(self, request, queryset, view):
"""
Apply incoming filters only if user is staff. If not, only filter by user's ID.
Apply incoming filters only if user is staff. If not, only filter by user's ID, email, or username.
"""
if request.user.is_staff:
queryset = self._filter_by_user_attributes(request, queryset)
Expand All @@ -142,6 +156,7 @@ def filter_queryset(self, request, queryset, view):
else:
queryset = queryset.filter(user_id=request.user.id)

queryset = self._filter_by_username_or_email(request, queryset)
return queryset


Expand Down
38 changes: 37 additions & 1 deletion enterprise/api/v1/views/enterprise_customer_user.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
"""
Views for the ``enterprise-customer-user`` API endpoint.
"""
from collections import OrderedDict

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
from rest_framework.response import Response

from enterprise import models
from enterprise.api.filters import EnterpriseCustomerUserFilterBackend
from enterprise.api.pagination import PaginationWithFeatureFlags
from enterprise.api.v1 import serializers
from enterprise.api.v1.views.base_views import EnterpriseReadWriteModelViewSet
from enterprise.toggles import enterprise_features


def _single_page_pagination(results):
return OrderedDict([
('count', len(results)),
('next', None),
('previous', None),
('results', results),
('enterprise_features', enterprise_features()),
])


class EnterpriseCustomerUserViewSet(EnterpriseReadWriteModelViewSet):
Expand All @@ -24,7 +38,29 @@ class EnterpriseCustomerUserViewSet(EnterpriseReadWriteModelViewSet):
'enterprise_customer', 'user_id', 'active',
)
filterset_fields = FIELDS
ordering_fields = FIELDS
ordering_fields = FIELDS + ('created',)

def list(self, request, *args, **kwargs):
"""
Enterprise Customer User's Basic data list without pagination
Besides what is laid out in filterset_fields and ordering_fields the following parameters are supported:
- username_or_email: filter by name or email substring in a single query parameter
- ordering=(-)username: Order by name
"""
queryset = self.get_queryset()
queryset = self.filter_queryset(queryset)
serializer = self.get_serializer(queryset, many=True)
# Manually sort by username
final_result = serializer.data
if ordering := request.query_params.get('ordering', None):
if 'username' in ordering:
def username_key(learner):
return learner['user']['username']
is_descending = ordering[0] == '-'
final_result = sorted(final_result, key=username_key, reverse=is_descending)

Check warning on line 61 in enterprise/api/v1/views/enterprise_customer_user.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/v1/views/enterprise_customer_user.py#L58-L61

Added lines #L58 - L61 were not covered by tests
paginated_result = _single_page_pagination(final_result)
return Response(paginated_result)

def get_serializer_class(self):
"""
Expand Down

0 comments on commit 0f35b9c

Please sign in to comment.