Skip to content

Commit

Permalink
changes in LearnerBaseSErailizer
Browse files Browse the repository at this point in the history
  • Loading branch information
tehreem-sadat committed Nov 20, 2024
1 parent 7490447 commit e35c17a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 42 deletions.
3 changes: 1 addition & 2 deletions futurex_openedx_extensions/dashboard/details/learners.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,5 @@ def get_learners_enrollments_queryset(
default=Value(False),
output_field=BooleanField(),
)
)

).select_related('user', 'user__profile')
return queryset
107 changes: 67 additions & 40 deletions futurex_openedx_extensions/dashboard/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ class LearnerBasicDetailsSerializer(ModelSerializerOptionalFields):
user_id = serializers.SerializerMethodField()
full_name = serializers.SerializerMethodField()
alternative_full_name = serializers.SerializerMethodField()
username = serializers.CharField()
username = serializers.SerializerMethodField()
national_id = serializers.SerializerMethodField()
email = serializers.EmailField()
email = serializers.SerializerMethodField()
mobile_no = serializers.SerializerMethodField()
year_of_birth = serializers.SerializerMethodField()
gender = serializers.SerializerMethodField()
gender_display = serializers.SerializerMethodField()
date_joined = serializers.DateTimeField()
last_login = serializers.DateTimeField()
date_joined = serializers.SerializerMethodField()
last_login = serializers.SerializerMethodField()

class Meta:
model = get_user_model()
Expand Down Expand Up @@ -118,6 +118,16 @@ def _is_english(text: str) -> bool:
"""
return all(ord(char) < 128 for char in text)

def _get_user(self, obj: Any = None) -> get_user_model | None: # pylint: disable=no-self-use
"""
Retrieve the associated user for the given object.
This method can be overridden in child classes to provide a different
implementation for accessing the user, depending on how the user is
related to the object (e.g., `obj.user`, `obj.profile.user`, etc.).
"""
return obj

def _get_name(self, obj: Any, alternative: bool = False) -> str:
"""
Calculate the full name and alternative full name. We have two issues in the data:
Expand All @@ -130,8 +140,8 @@ def _get_name(self, obj: Any, alternative: bool = False) -> str:
:type alternative: bool
:return: The full name or alternative full name.
"""
first_name = obj.first_name.strip()
last_name = obj.last_name.strip()
first_name = self._get_user(obj).first_name.strip() # type: ignore
last_name = self._get_user(obj).last_name.strip() # type: ignore

full_name = first_name or last_name
if first_name and last_name and not (first_name == last_name and ' ' in first_name):
Expand Down Expand Up @@ -167,20 +177,36 @@ def _get_arabic_name(self, obj: Any) -> str:
arabic_full_name = ' '.join(filter(None, (arabic_first_name, arabic_last_name)))
return (arabic_full_name or '').strip()

@staticmethod
def _get_profile_field(obj: get_user_model, field_name: str) -> Any:
def _get_profile_field(self: Any, obj: get_user_model, field_name: str) -> Any:
"""Get the profile field value."""
return getattr(obj.profile, field_name) if hasattr(obj, 'profile') and obj.profile else None
user = self._get_user(obj)
return getattr(user.profile, field_name) if hasattr(user, 'profile') and user.profile else None

@staticmethod
def _get_extra_field(obj: get_user_model, field_name: str) -> Any:
def _get_extra_field(self: Any, obj: get_user_model, field_name: str) -> Any:
"""Get the extra field value."""
return getattr(obj.extrainfo, field_name) if hasattr(obj, 'extrainfo') and obj.extrainfo else None
user = self._get_user(obj)
return getattr(user.extrainfo, field_name) if hasattr(user, 'extrainfo') and user.extrainfo else None

def get_user_id(self, obj: get_user_model) -> Any: # pylint: disable=no-self-use
"""Return user ID."""
return obj.id

def get_email(self, obj: get_user_model) -> str:
"""Return user ID."""
return self._get_user(obj).email # type: ignore

def get_username(self, obj: get_user_model) -> str:
"""Return user ID."""
return self._get_user(obj).username # type: ignore

def get_date_joined(self, obj: get_user_model) -> str:
"""Return user ID."""
return str(self._get_user(obj).date_joined) # type: ignore

def get_last_login(self, obj: get_user_model) -> str:
"""Return user ID."""
return str(self._get_user(obj).last_login) # type: ignore

def get_national_id(self, obj: get_user_model) -> Any:
"""Return national ID."""
return self._get_extra_field(obj, 'national_id')
Expand Down Expand Up @@ -210,27 +236,6 @@ def get_year_of_birth(self, obj: get_user_model) -> Any:
return self._get_profile_field(obj, 'year_of_birth')


class LearnerDetailsSerializer(LearnerBasicDetailsSerializer):
"""Serializer for learner details."""
enrolled_courses_count = serializers.SerializerMethodField()
certificates_count = serializers.SerializerMethodField()

class Meta:
model = get_user_model()
fields = LearnerBasicDetailsSerializer.Meta.fields + [
'enrolled_courses_count',
'certificates_count',
]

def get_certificates_count(self, obj: get_user_model) -> Any: # pylint: disable=no-self-use
"""Return certificates count."""
return obj.certificates_count

def get_enrolled_courses_count(self, obj: get_user_model) -> Any: # pylint: disable=no-self-use
"""Return enrolled courses count."""
return obj.courses_count


class CourseScoreAndCertificateSerializer(ModelSerializerOptionalFields):
"""
Course Score and Certificate Details Serializer
Expand Down Expand Up @@ -346,6 +351,27 @@ def _extract_exam_scores(representation_item: dict[str, Any]) -> None:
return representation


class LearnerDetailsSerializer(LearnerBasicDetailsSerializer):
"""Serializer for learner details."""
enrolled_courses_count = serializers.SerializerMethodField()
certificates_count = serializers.SerializerMethodField()

class Meta:
model = get_user_model()
fields = LearnerBasicDetailsSerializer.Meta.fields + [
'enrolled_courses_count',
'certificates_count',
]

def get_certificates_count(self, obj: get_user_model) -> Any: # pylint: disable=no-self-use
"""Return certificates count."""
return obj.certificates_count

def get_enrolled_courses_count(self, obj: get_user_model) -> Any: # pylint: disable=no-self-use
"""Return enrolled courses count."""
return obj.courses_count


class LearnerDetailsForCourseSerializer(
LearnerBasicDetailsSerializer, CourseScoreAndCertificateSerializer
): # pylint: disable=too-many-ancestors
Expand All @@ -370,13 +396,19 @@ def _get_user(self, obj: Any = None) -> get_user_model:
return obj


class LearnerEnrollmentSerializer(CourseScoreAndCertificateSerializer):
class LearnerEnrollmentSerializer(
LearnerBasicDetailsSerializer, CourseScoreAndCertificateSerializer
): # pylint: disable=too-many-ancestors
"""Serializer for learner enrollments"""
course_id = serializers.SerializerMethodField()

class Meta:
model = CourseEnrollment
fields = CourseScoreAndCertificateSerializer.Meta.fields + ['course_id']
fields = (
LearnerBasicDetailsSerializer.Meta.fields +
CourseScoreAndCertificateSerializer.Meta.fields +
['course_id']
)

def __init__(self, *args: Any, **kwargs: Any):
"""Initialize the serializer."""
Expand All @@ -396,11 +428,6 @@ def get_course_id(self, obj: Any) -> str:
"""Get course id"""
return str(self._get_course_id(obj))

def to_representation(self, instance: Any) -> Any:
representation = LearnerBasicDetailsSerializer(self._get_user(instance)).data
representation.update(super().to_representation(instance))
return representation


class LearnerDetailsExtendedSerializer(LearnerDetailsSerializer): # pylint: disable=too-many-ancestors
"""Serializer for extended learner details."""
Expand Down

0 comments on commit e35c17a

Please sign in to comment.