From 81c838e70ae6e695fd7eaa56292d6b79da827992 Mon Sep 17 00:00:00 2001 From: yaswanth sai vendra <75136628+yaswanthsaivendra@users.noreply.github.com> Date: Thu, 20 Jul 2023 21:36:44 +0530 Subject: [PATCH] =?UTF-8?q?prefetched=20skills=20for=20userassigned=20seri?= =?UTF-8?q?alizer=20in=20patientconsultation=20=E2=80=A6=20(#1370)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * prefetched skills for userassigned serializer in patientconsultation and facilityusers view * added tests for code changes * refactor tests --------- Co-authored-by: Aakash Singh Co-authored-by: Vignesh Hari --- care/facility/api/viewsets/facility_users.py | 11 +++- .../api/viewsets/patient_consultation.py | 11 +++- care/facility/tests/test_facilityuser_api.py | 47 +++++++++++++++++ .../tests/test_patient_consultation_api.py | 50 +++++++++++++++++-- care/users/api/serializers/user.py | 6 +-- 5 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 care/facility/tests/test_facilityuser_api.py diff --git a/care/facility/api/viewsets/facility_users.py b/care/facility/api/viewsets/facility_users.py index 8422991791..a03319ecf8 100644 --- a/care/facility/api/viewsets/facility_users.py +++ b/care/facility/api/viewsets/facility_users.py @@ -1,3 +1,4 @@ +from django.db.models import Prefetch from django_filters import rest_framework as filters from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import mixins @@ -7,7 +8,7 @@ from care.facility.models.facility import Facility from care.users.api.serializers.user import UserAssignedSerializer -from care.users.models import User +from care.users.models import Skill, User class UserFilter(filters.FilterSet): @@ -34,6 +35,12 @@ def get_queryset(self): facility = Facility.objects.get( external_id=self.kwargs.get("facility_external_id") ) - return facility.users.filter(deleted=False).order_by("-last_login") + queryset = facility.users.filter(deleted=False).order_by("-last_login") + queryset = queryset.prefetch_related( + Prefetch( + "skills", queryset=Skill.objects.filter(userskill__deleted=False) + ) + ) + return queryset except Facility.DoesNotExist: raise ValidationError({"Facility": "Facility not found"}) diff --git a/care/facility/api/viewsets/patient_consultation.py b/care/facility/api/viewsets/patient_consultation.py index dc18b65851..98b60ba393 100644 --- a/care/facility/api/viewsets/patient_consultation.py +++ b/care/facility/api/viewsets/patient_consultation.py @@ -1,3 +1,4 @@ +from django.db.models import Prefetch from django.db.models.query_utils import Q from django_filters import rest_framework as filters from drf_spectacular.utils import extend_schema @@ -24,7 +25,7 @@ email_discharge_summary, generate_and_upload_discharge_summary_task, ) -from care.users.models import User +from care.users.models import Skill, User from care.utils.cache.cache_allowed_facilities import get_accessible_facilities @@ -69,6 +70,14 @@ def get_permissions(self): return super().get_permissions() def get_queryset(self): + if self.serializer_class == PatientConsultationSerializer: + self.queryset = self.queryset.prefetch_related( + "assigned_to", + Prefetch( + "assigned_to__skills", + queryset=Skill.objects.filter(userskill__deleted=False), + ), + ) if self.request.user.is_superuser: return self.queryset elif self.request.user.user_type >= User.TYPE_VALUE_MAP["StateLabAdmin"]: diff --git a/care/facility/tests/test_facilityuser_api.py b/care/facility/tests/test_facilityuser_api.py new file mode 100644 index 0000000000..0e9d35edec --- /dev/null +++ b/care/facility/tests/test_facilityuser_api.py @@ -0,0 +1,47 @@ +from django.test import TestCase +from rest_framework import status + +from care.facility.api.viewsets.facility_users import FacilityUserViewSet +from care.facility.models.facility import Facility +from care.facility.tests.mixins import TestClassMixin +from care.users.models import Skill + + +class FacilityUserTest(TestClassMixin, TestCase): + def setUp(self): + super().setUp() + self.creator = self.users[0] + + sample_data = { + "name": "Hospital X", + "ward": self.creator.ward, + "local_body": self.creator.local_body, + "district": self.creator.district, + "state": self.creator.state, + "facility_type": 1, + "address": "Nearby", + "pincode": 390024, + "features": [], + } + self.facility = Facility.objects.create( + external_id="550e8400-e29b-41d4-a716-446655440000", + created_by=self.creator, + **sample_data, + ) + + self.skill1 = Skill.objects.create(name="Skill 1") + self.skill2 = Skill.objects.create(name="Skill 2") + + self.users[0].skills.add(self.skill1, self.skill2) + + def test_get_queryset_with_prefetching(self): + response = self.new_request( + (f"/api/v1/facility/{self.facility.external_id}/get_users/",), + {"get": "list"}, + FacilityUserViewSet, + self.users[0], + {"facility_external_id": self.facility.external_id}, + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertNumQueries(2) diff --git a/care/facility/tests/test_patient_consultation_api.py b/care/facility/tests/test_patient_consultation_api.py index 82e6a914ab..ff55865c27 100644 --- a/care/facility/tests/test_patient_consultation_api.py +++ b/care/facility/tests/test_patient_consultation_api.py @@ -1,18 +1,62 @@ import datetime +from django.test import TestCase from django.utils.timezone import make_aware from rest_framework import status from rest_framework.test import APIRequestFactory, APITestCase +from care.facility.api.viewsets.facility_users import FacilityUserViewSet from care.facility.api.viewsets.patient_consultation import PatientConsultationViewSet +from care.facility.models.facility import Facility from care.facility.models.patient_consultation import ( CATEGORY_CHOICES, PatientConsultation, ) from care.facility.tests.mixins import TestClassMixin +from care.users.models import Skill from care.utils.tests.test_base import TestBase +class FacilityUserTest(TestClassMixin, TestCase): + def setUp(self): + super().setUp() + self.creator = self.users[0] + + sample_data = { + "name": "Hospital X", + "ward": self.creator.ward, + "local_body": self.creator.local_body, + "district": self.creator.district, + "state": self.creator.state, + "facility_type": 1, + "address": "Nearby", + "pincode": 390024, + "features": [], + } + self.facility = Facility.objects.create( + external_id="550e8400-e29b-41d4-a716-446655440000", + created_by=self.creator, + **sample_data, + ) + + self.skill1 = Skill.objects.create(name="Skill 1") + self.skill2 = Skill.objects.create(name="Skill 2") + + self.users[0].skills.add(self.skill1, self.skill2) + + def test_get_queryset_with_prefetching(self): + response = self.new_request( + (f"/api/v1/facility/{self.facility.external_id}/get_users/",), + {"get": "list"}, + FacilityUserViewSet, + self.users[0], + {"facility_external_id": self.facility.external_id}, + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertNumQueries(2) + + class TestPatientConsultation(TestBase, TestClassMixin, APITestCase): default_data = { "symptoms": [1], @@ -31,11 +75,7 @@ def setUp(self): ) def create_admission_consultation(self, patient=None, **kwargs): - patient = ( - self.create_patient(facility_id=self.facility.id) - if not patient - else patient - ) + patient = patient or self.create_patient(facility_id=self.facility.id) data = self.default_data.copy() kwargs.update( { diff --git a/care/users/api/serializers/user.py b/care/users/api/serializers/user.py index c1fb589171..61fff8759a 100644 --- a/care/users/api/serializers/user.py +++ b/care/users/api/serializers/user.py @@ -353,11 +353,7 @@ class UserAssignedSerializer(serializers.ModelSerializer): home_facility_object = FacilityBareMinimumSerializer( source="home_facility", read_only=True ) - skills = serializers.SerializerMethodField() - - def get_skills(self, obj): - qs = obj.skills.filter(userskill__deleted=False) - return SkillSerializer(qs, many=True).data + skills = SkillSerializer(many=True, read_only=True) class Meta: model = User