Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: filter and sort learner by name/email #2284

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@

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_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 @@
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 @@
'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
Loading