Merge pull request #17477 from open-craft/ciuin/improve-courseenrollment-admin-search-upstream
Improve CourseEnrollment admin search presentation
This commit is contained in:
@@ -5,6 +5,7 @@ from django.contrib import admin
|
||||
from django.contrib.admin.sites import NotRegistered
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
@@ -181,6 +182,21 @@ class CourseEnrollmentAdmin(admin.ModelAdmin):
|
||||
search_fields = ('course__id', 'mode', 'user__username',)
|
||||
form = CourseEnrollmentForm
|
||||
|
||||
def get_search_results(self, request, queryset, search_term):
|
||||
qs, use_distinct = super(CourseEnrollmentAdmin, self).get_search_results(request, queryset, search_term)
|
||||
|
||||
# annotate each enrollment with whether the username was an
|
||||
# exact match for the search term
|
||||
qs = qs.annotate(exact_username_match=models.Case(
|
||||
models.When(user__username=search_term, then=models.Value(True)),
|
||||
default=models.Value(False),
|
||||
output_field=models.BooleanField()))
|
||||
|
||||
# present exact matches first
|
||||
qs = qs.order_by('-exact_username_match', 'user__username', 'course_id')
|
||||
|
||||
return qs, use_distinct
|
||||
|
||||
def queryset(self, request):
|
||||
return super(CourseEnrollmentAdmin, self).queryset(request).select_related('user')
|
||||
|
||||
|
||||
@@ -208,11 +208,12 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
def setUp(self):
|
||||
super(CourseEnrollmentAdminTest, self).setUp()
|
||||
self.user = UserFactory.create(is_staff=True, is_superuser=True)
|
||||
self.client.login(username=self.user.username, password='test')
|
||||
self.course = CourseFactory()
|
||||
CourseEnrollmentFactory(
|
||||
user=self.user,
|
||||
course_id=CourseFactory().id, # pylint: disable=no-member
|
||||
course_id=self.course.id, # pylint: disable=no-member
|
||||
)
|
||||
self.client.login(username=self.user.username, password='test')
|
||||
|
||||
@ddt.data(*ADMIN_URLS)
|
||||
@ddt.unpack
|
||||
@@ -232,3 +233,24 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
with COURSE_ENROLLMENT_ADMIN_SWITCH.override(active=True):
|
||||
response = getattr(self.client, method)(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_username_exact_match(self):
|
||||
"""
|
||||
Ensure that course enrollment searches return exact matches on username first.
|
||||
"""
|
||||
user2 = UserFactory.create(username='aaa_{}'.format(self.user.username))
|
||||
CourseEnrollmentFactory(
|
||||
user=user2,
|
||||
course_id=self.course.id, # pylint: disable=no-member
|
||||
)
|
||||
search_url = '{}?q={}'.format(reverse('admin:student_courseenrollment_changelist'), self.user.username)
|
||||
with COURSE_ENROLLMENT_ADMIN_SWITCH.override(active=True):
|
||||
response = self.client.get(search_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# context['results'] is an array of arrays of HTML <td> elements to be rendered
|
||||
self.assertEqual(len(response.context['results']), 2)
|
||||
for idx, username in enumerate([self.user.username, user2.username]):
|
||||
# Locate the <td> column containing the username
|
||||
user_field = next(col for col in response.context['results'][idx] if "field-user" in col)
|
||||
self.assertIn(username, user_field)
|
||||
|
||||
Reference in New Issue
Block a user