Skip to content

Commit

Permalink
wip: fix using a separate manager
Browse files Browse the repository at this point in the history
  • Loading branch information
Cup0fCoffee committed Apr 11, 2023
1 parent ebbfd02 commit 91be371
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 50 deletions.
68 changes: 19 additions & 49 deletions enterprise/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,6 @@
)
from enterprise.validators import validate_pgp_key

try:
from common.djangoapps.student.models import CourseEnrollment
except ImportError:
CourseEnrollment = None

try:
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
except ImportError:
CourseOverview = None

LOGGER = getLogger(__name__)
User = auth.get_user_model()

Expand Down Expand Up @@ -336,8 +326,7 @@ class EnterpriseCourseEnrollmentReadOnlySerializer(serializers.ModelSerializer):
class Meta:
model = models.EnterpriseCourseEnrollment
fields = (
'enterprise_customer_user',
'course_id',
'enterprise_customer_user', 'course_id',
)


Expand All @@ -346,44 +335,25 @@ class EnterpriseCourseEnrollmentWithAdditionalFieldsReadOnlySerializer(Enterpris
Serializer for EnterpriseCourseEnrollment model with additional fields.
"""

def to_representation(self, instance):
representation = super().to_representation(instance)
representation.update(self._get_additional_fields(instance))
return representation

def _get_additional_fields(self, instance):
"""
Return annotations with additional data for the queryset.
Additional fields are None in the test environment, where platform models are not available.
"""

if not CourseEnrollment or not CourseOverview:
return {
'enrollment_track': None,
'enrollment_date': None,
'user_email': None,
'course_start': None,
'course_end': None,
}

user = auth.get_user_model().objects.filter(
id=instance.enterprise_customer_user.user_id,
).first()
enrollment = CourseEnrollment.objects.filter(
user=user,
course_id=instance.course_id,
).first()
course_overview = CourseOverview.objects.filter(
id=instance.course_id,
).first()
class Meta:
model = models.EnterpriseCourseEnrollment
fields = (
'enterprise_customer_user',
'course_id',
'enterprise_customer_user',
'course_id',
'enrollment_date',
'enrollment_track',
'user_email',
'course_start',
'course_end',
)

return {
'enrollment_track': getattr(enrollment, 'mode', None),
'enrollment_date': getattr(enrollment, 'created', None),
'user_email': getattr(user, 'email', None),
'course_start': getattr(course_overview, 'start', None),
'course_end': getattr(course_overview, 'end', None),
}
enrollment_track = serializers.CharField()
enrollment_date = serializers.DateTimeField()
user_email = serializers.EmailField()
course_start = serializers.DateTimeField()
course_end = serializers.DateTimeField()


class EnterpriseCourseEnrollmentWriteSerializer(serializers.ModelSerializer):
Expand Down
2 changes: 1 addition & 1 deletion enterprise/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ class EnterpriseCourseEnrollmentViewSet(EnterpriseReadWriteModelViewSet):
API views for the ``enterprise-course-enrollment`` API endpoint.
"""

queryset = models.EnterpriseCourseEnrollment.objects.all()
queryset = models.EnterpriseCourseEnrollment.with_additional_fields.all()
filter_backends = (filters.OrderingFilter, DjangoFilterBackend, EnterpriseCourseEnrollmentFilterBackend)

USER_ID_FILTER = 'enterprise_customer_user__user_id'
Expand Down
54 changes: 54 additions & 0 deletions enterprise/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@
except ImportError:
CourseEntitlement = None

try:
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
except ImportError:
CourseOverview = None

LOGGER = getLogger(__name__)
User = auth.get_user_model()
mark_safe_lazy = lazy(mark_safe, str)
Expand Down Expand Up @@ -1786,6 +1791,54 @@ def get_queryset(self):
enterprise_customer_user__linked=True
)

class EnterpriseCourseEnrollmentWithAdditionalFieldsManager(models.Manager):
"""
Model manager for `EnterpriseCourseEnrollment`.
"""

def get_queryset(self):
"""
Override to return only those enrollment records for which learner is linked to an enterprise.
"""

return super().get_queryset().select_related('enterprise_customer_user').filter(
enterprise_customer_user__linked=True
).annotate(**self._get_additional_data_annotations())

def _get_additional_data_annotations(self):
"""
Return annotations with additional data for the queryset.
Additional fields are None in the test environment, where platform models are not available.
"""

if not CourseEnrollment or not CourseOverview:
return {
'enrollment_track': models.Value(None, output_field=models.CharField()),
'enrollment_date': models.Value(None, output_field=models.DateTimeField()),
'user_email': models.Value(None, output_field=models.EmailField()),
'course_start': models.Value(None, output_field=models.DateTimeField()),
'course_end': models.Value(None, output_field=models.DateTimeField()),
}

enrollment_subquery = CourseEnrollment.objects.filter(
user=models.OuterRef('enterprise_customer_user__user_id'),
course_id=models.OuterRef('course_id'),
)
user_subquery = auth.get_user_model().objects.filter(
id=models.OuterRef('enterprise_customer_user__user_id'),
).values('email')[:1]
course_subquery = CourseOverview.objects.filter(
id=models.OuterRef('course_id'),
)

return {
'enrollment_track': models.Subquery(enrollment_subquery.values('mode')[:1]),
'enrollment_date': models.Subquery(enrollment_subquery.values('created')[:1]),
'user_email': models.Subquery(user_subquery),
'course_start': models.Subquery(course_subquery.values('start')[:1]),
'course_end': models.Subquery(course_subquery.values('end')[:1]),
}


class EnterpriseCourseEnrollment(TimeStampedModel):
"""
Expand All @@ -1806,6 +1859,7 @@ class EnterpriseCourseEnrollment(TimeStampedModel):
"""

objects = EnterpriseCourseEnrollmentManager()
with_additional_fields = EnterpriseCourseEnrollmentWithAdditionalFieldsManager()

class Meta:
unique_together = (('enterprise_customer_user', 'course_id',),)
Expand Down

0 comments on commit 91be371

Please sign in to comment.