From b88a61e48960e38c3c8669aa47bcb0dd142fdf6c Mon Sep 17 00:00:00 2001 From: Muhammed Zafar Date: Tue, 17 Oct 2023 22:01:04 +0530 Subject: [PATCH 1/4] [OPTIM] Leaderboard patches (#1348) --- api/leaderboard/leaderboard_view.py | 34 ++++++++++++++++------------- api/leaderboard/serializers.py | 26 +++++++++++++++++----- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/api/leaderboard/leaderboard_view.py b/api/leaderboard/leaderboard_view.py index 3f206840..65811990 100644 --- a/api/leaderboard/leaderboard_view.py +++ b/api/leaderboard/leaderboard_view.py @@ -1,7 +1,8 @@ -from django.db.models import Sum, F, Value, OuterRef, Subquery, Count, Q +from django.db.models import Sum, F, Value, OuterRef, Subquery, Count, Q, Prefetch from django.db.models.functions import Concat, Coalesce from rest_framework.views import APIView import datetime +from . import serializers from db.organization import Organization, UserOrganizationLink from db.user import User @@ -12,14 +13,6 @@ class StudentsLeaderboard(APIView): def get(self, request): - user_college = ( - UserOrganizationLink.objects.filter( - user_id=OuterRef("id"), org__org_type=OrganizationType.COLLEGE.value - ) - .order_by("id") - .values("org__title")[:1] - ) - students_leaderboard = ( User.objects.filter( user_organization_link_user__org__org_type=OrganizationType.COLLEGE.value, @@ -28,14 +21,25 @@ def get(self, request): active=True, ) .distinct() - .values( - total_karma=F("wallet_user__karma"), - full_name=Concat(F("first_name"), Value(" "), F("last_name")), - institution=Subquery(user_college), + .select_related("wallet_user") + .prefetch_related( + Prefetch( + "user_organization_link_user", + queryset=UserOrganizationLink.objects.filter( + org__org_type=OrganizationType.COLLEGE.value + ).select_related("org"), + to_attr="colleges" + ) ) - .order_by("-total_karma")[:20] + .order_by("-wallet_user__karma")[:20] + ) + serialized_students_leaderboard = serializers.StudentLeaderboardSerializer( + students_leaderboard, many=True ) - return CustomResponse(response=students_leaderboard).get_success_response() + + return CustomResponse( + response=serialized_students_leaderboard.data + ).get_success_response() class StudentsMonthlyLeaderboard(APIView): diff --git a/api/leaderboard/serializers.py b/api/leaderboard/serializers.py index fb591aba..e35a4dc3 100644 --- a/api/leaderboard/serializers.py +++ b/api/leaderboard/serializers.py @@ -5,6 +5,7 @@ from db.organization import UserOrganizationLink from db.task import KarmaActivityLog +from db.user import User from utils.types import OrganizationType from utils.utils import DateTimeUtils @@ -46,12 +47,12 @@ def get_active_members(self, obj): def get_total_karma(self, obj): return ( - obj.org.user_organization_link_org.filter( - org__org_type=OrganizationType.COLLEGE.value, - verified=True, - user__wallet_user__isnull=False, - ).aggregate(total_karma=Sum("user__wallet_user__karma"))["total_karma"] - or 0 + obj.org.user_organization_link_org.filter( + org__org_type=OrganizationType.COLLEGE.value, + verified=True, + user__wallet_user__isnull=False, + ).aggregate(total_karma=Sum("user__wallet_user__karma"))["total_karma"] + or 0 ) def get_rank(self, obj): @@ -74,3 +75,16 @@ def get_rank(self, obj): keys_list = list(sorted_rank_dict.keys()) position = keys_list.index(obj.org.id) return position + 1 + + +class StudentLeaderboardSerializer(serializers.ModelSerializer): + institution = serializers.SerializerMethodField() + total_karma = serializers.IntegerField(source="wallet_user.karma", default=0) + full_name = serializers.CharField(source="fullname") + + def get_institution(self, user): + return user.colleges[0].org.title if user.colleges else None + + class Meta: + model = User + fields = ["full_name", "total_karma", "institution"] From 4417a3084a85b47b7a47cf8ed9029db82d750ba4 Mon Sep 17 00:00:00 2001 From: Muhammed Zafar Date: Tue, 17 Oct 2023 22:01:49 +0530 Subject: [PATCH 2/4] [OPTIM] Leaderboard patches (#1349) --- api/leaderboard/leaderboard_view.py | 34 ++++++++++++++++------------- api/leaderboard/serializers.py | 26 +++++++++++++++++----- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/api/leaderboard/leaderboard_view.py b/api/leaderboard/leaderboard_view.py index 3f206840..65811990 100644 --- a/api/leaderboard/leaderboard_view.py +++ b/api/leaderboard/leaderboard_view.py @@ -1,7 +1,8 @@ -from django.db.models import Sum, F, Value, OuterRef, Subquery, Count, Q +from django.db.models import Sum, F, Value, OuterRef, Subquery, Count, Q, Prefetch from django.db.models.functions import Concat, Coalesce from rest_framework.views import APIView import datetime +from . import serializers from db.organization import Organization, UserOrganizationLink from db.user import User @@ -12,14 +13,6 @@ class StudentsLeaderboard(APIView): def get(self, request): - user_college = ( - UserOrganizationLink.objects.filter( - user_id=OuterRef("id"), org__org_type=OrganizationType.COLLEGE.value - ) - .order_by("id") - .values("org__title")[:1] - ) - students_leaderboard = ( User.objects.filter( user_organization_link_user__org__org_type=OrganizationType.COLLEGE.value, @@ -28,14 +21,25 @@ def get(self, request): active=True, ) .distinct() - .values( - total_karma=F("wallet_user__karma"), - full_name=Concat(F("first_name"), Value(" "), F("last_name")), - institution=Subquery(user_college), + .select_related("wallet_user") + .prefetch_related( + Prefetch( + "user_organization_link_user", + queryset=UserOrganizationLink.objects.filter( + org__org_type=OrganizationType.COLLEGE.value + ).select_related("org"), + to_attr="colleges" + ) ) - .order_by("-total_karma")[:20] + .order_by("-wallet_user__karma")[:20] + ) + serialized_students_leaderboard = serializers.StudentLeaderboardSerializer( + students_leaderboard, many=True ) - return CustomResponse(response=students_leaderboard).get_success_response() + + return CustomResponse( + response=serialized_students_leaderboard.data + ).get_success_response() class StudentsMonthlyLeaderboard(APIView): diff --git a/api/leaderboard/serializers.py b/api/leaderboard/serializers.py index fb591aba..e35a4dc3 100644 --- a/api/leaderboard/serializers.py +++ b/api/leaderboard/serializers.py @@ -5,6 +5,7 @@ from db.organization import UserOrganizationLink from db.task import KarmaActivityLog +from db.user import User from utils.types import OrganizationType from utils.utils import DateTimeUtils @@ -46,12 +47,12 @@ def get_active_members(self, obj): def get_total_karma(self, obj): return ( - obj.org.user_organization_link_org.filter( - org__org_type=OrganizationType.COLLEGE.value, - verified=True, - user__wallet_user__isnull=False, - ).aggregate(total_karma=Sum("user__wallet_user__karma"))["total_karma"] - or 0 + obj.org.user_organization_link_org.filter( + org__org_type=OrganizationType.COLLEGE.value, + verified=True, + user__wallet_user__isnull=False, + ).aggregate(total_karma=Sum("user__wallet_user__karma"))["total_karma"] + or 0 ) def get_rank(self, obj): @@ -74,3 +75,16 @@ def get_rank(self, obj): keys_list = list(sorted_rank_dict.keys()) position = keys_list.index(obj.org.id) return position + 1 + + +class StudentLeaderboardSerializer(serializers.ModelSerializer): + institution = serializers.SerializerMethodField() + total_karma = serializers.IntegerField(source="wallet_user.karma", default=0) + full_name = serializers.CharField(source="fullname") + + def get_institution(self, user): + return user.colleges[0].org.title if user.colleges else None + + class Meta: + model = User + fields = ["full_name", "total_karma", "institution"] From b8d7049eb5cdb03538e2a1570c97c3619da80165 Mon Sep 17 00:00:00 2001 From: Muhammed Zafar Date: Tue, 17 Oct 2023 22:25:27 +0530 Subject: [PATCH 3/4] [PATCH] User EDIT dashboard (#1350) * [PATCH] User edit GET (#1337) * [OPTIM] Leaderboard patches * [OPTIM] Leaderboard patches (#1349) * [PATCH] User EDIT dashboard --------- Co-authored-by: Adnan Kattekaden <71538497+adnankattekaden@users.noreply.github.com> --- api/dashboard/user/dash_user_serializer.py | 50 +++++++--------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/api/dashboard/user/dash_user_serializer.py b/api/dashboard/user/dash_user_serializer.py index b9ad1bee..30d1633b 100644 --- a/api/dashboard/user/dash_user_serializer.py +++ b/api/dashboard/user/dash_user_serializer.py @@ -60,17 +60,16 @@ def get_roles(self, obj): class CollegeSerializer(serializers.ModelSerializer): - title = serializers.CharField(source="org.title", allow_null=True) org_type = serializers.CharField(source="org.org_type") - department = serializers.CharField(source="department.title") - country = serializers.CharField(source="country.name") - state = serializers.CharField(source="state.name") - district = serializers.CharField(source="district.name") + department = serializers.CharField(source="department.pk") + country = serializers.CharField(source="country.pk") + state = serializers.CharField(source="state.pk") + district = serializers.CharField(source="district.pk") class Meta: model = UserOrganizationLink fields = [ - "title", + "org", "org_type", "department", "graduation_year", @@ -80,33 +79,25 @@ class Meta: ] -class CommunitySerializer(serializers.ModelSerializer): - title = serializers.CharField(source="org.title", read_only=True) +class OrgSerializer(serializers.ModelSerializer): org_type = serializers.CharField(source="org.org_type", read_only=True) class Meta: model = UserOrganizationLink - fields = ["title", "org_type"] - - -class CompanySerializer(serializers.ModelSerializer): - title = serializers.CharField(source="org.title", read_only=True) - org_type = serializers.CharField(source="org.org_type", read_only=True) - - class Meta: - model = UserOrganizationLink - fields = ["title", "org_type"] + fields = ["org", "org_type"] class UserDetailsSerializer(serializers.ModelSerializer): user_id = serializers.CharField(source="id") - organizations = serializers.SerializerMethodField(read_only=True) - interest_groups = serializers.SerializerMethodField(read_only=True) + igs = serializers.ListField(write_only=True) - role = serializers.SerializerMethodField(read_only=True) department = serializers.CharField(write_only=True) graduation_year = serializers.CharField(write_only=True) + organizations = serializers.SerializerMethodField(read_only=True) + interest_groups = serializers.SerializerMethodField(read_only=True) + role = serializers.SerializerMethodField(read_only=True) + class Meta: model = User fields = [ @@ -125,7 +116,7 @@ class Meta: "interest_groups", "igs", ] - + def validate(self, data): if "id" not in data: raise serializers.ValidationError("User id is a required field") @@ -193,26 +184,17 @@ def get_organizations(self, user): for link in organization_links: if link.org.org_type == OrganizationType.COLLEGE.value: serializer = CollegeSerializer(link) - elif link.org.org_type == OrganizationType.COMPANY.value: - serializer = CompanySerializer(link) else: - serializer = CommunitySerializer(link) + serializer = OrgSerializer(link) organizations_data.append(serializer.data) return organizations_data def get_interest_groups(self, user): - igs = user.user_ig_link_user.all() - if igs: - igs = [ig.ig.name for ig in igs] - return igs + return user.user_ig_link_user.all().values_list("ig", flat=True) def get_role(self, user): - if roles := UserRoleLink.objects.filter(user=user).values_list( - "role__title", flat=True - ): - return list(roles) - return None + return user.user_role_link_user.all().values_list("role", flat=True) class UserVerificationSerializer(serializers.ModelSerializer): From 0fa49a450b1ae66a15f54b566eac6f210621d4c8 Mon Sep 17 00:00:00 2001 From: Adnan Kattekaden Date: Tue, 17 Oct 2023 22:32:45 +0530 Subject: [PATCH 4/4] kkem college wise report --- api/common/common_views.py | 12 +++++++++++- api/common/urls.py | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/api/common/common_views.py b/api/common/common_views.py index 5e0c8d72..19b52caa 100644 --- a/api/common/common_views.py +++ b/api/common/common_views.py @@ -28,7 +28,7 @@ def get(self, request): learning_circle_count = LearningCircle.objects.all().count() total_no_enrollment = UserCircleLink.objects.filter(accepted=True).count() circle_count_by_ig = LearningCircle.objects.all().values(ig_name=F('ig__name')).annotate( - total_circles=Count('id')) + total_circles=Count('id'), total_users=Count('ig__learningcircle__usercirclelink__user', distinct=True)) unique_user_count = UserCircleLink.objects.filter(accepted=True).values('user').distinct().count() return CustomResponse(response={'lc_count': learning_circle_count, 'total_enrollment': total_no_enrollment, @@ -122,6 +122,16 @@ def get(self, request): return CommonUtils.generate_csv(student_info_data, "Learning Circle Report") +class CollegeWiseLcReport(APIView): + + def get(self, request): + learning_circles_info = LearningCircle.objects.filter(org__org_type=OrganizationType.COLLEGE.value).annotate( + user_count=Count('usercirclelink'), + org_name=F('org__title') + ).values('name', 'user_count', 'org_name') + return CustomResponse(response=learning_circles_info).get_success_response() + + class GlobalCountAPI(APIView): def get(self, request): diff --git a/api/common/urls.py b/api/common/urls.py index 14f20769..0a695775 100644 --- a/api/common/urls.py +++ b/api/common/urls.py @@ -5,6 +5,7 @@ urlpatterns = [ path('lc-dashboard/', common_views.LcDashboardAPI.as_view()), path('lc-report/', common_views.LcReportAPI.as_view()), + path('college-wise-lc-report/', common_views.CollegeWiseLcReport.as_view()), path('download/lc-report/', common_views.LcReportDownloadAPI.as_view()), path('global-count/', common_views.GlobalCountAPI.as_view()), ]