From eb3387b8286ca1327bd04ebf7333b6af988b18d4 Mon Sep 17 00:00:00 2001 From: Naman Sharma Date: Thu, 11 Dec 2025 13:13:02 +0000 Subject: [PATCH] Optimized test request page to reduce SQL queries --- events/forms.py | 52 ++++++++++++++++++++++++++++++++++++------------- events/views.py | 10 +++++++--- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/events/forms.py b/events/forms.py index 2e466b51b..094532cd9 100644 --- a/events/forms.py +++ b/events/forms.py @@ -287,16 +287,16 @@ class Meta(object): def clean_workshop(self): super(TestForm, self).clean() - if 'test_category' in self.cleaned_data: - if self.cleaned_data['test_category'].id == 1 and self.cleaned_data['workshop'] == '': - raise forms.ValidationError("Workshop field is required.") + test_category = self.cleaned_data.get('test_category') + if test_category and test_category.id == 1 and self.cleaned_data.get('workshop', '') == '': + raise forms.ValidationError("Workshop field is required.") def clean_training(self): super(TestForm, self).clean() - if 'test_category' in self.cleaned_data: - if self.cleaned_data['test_category'].id == 2 and self.cleaned_data['training'] == '': - raise forms.ValidationError("Training field is required.") - test_category = forms.ModelChoiceField(queryset = TestCategory.objects.filter(status=True), required = False) + test_category = self.cleaned_data.get('test_category') + if test_category and test_category.id == 2 and self.cleaned_data.get('training', '') == '': + raise forms.ValidationError("Training field is required.") + test_category = forms.ModelChoiceField(queryset=TestCategory.objects.filter(status=True), required=False) tdate = forms.DateTimeField(required = True, error_messages = {'required':'Date field is required.'}) #workshop = forms.ChoiceField(choices = [('', '-- None --'),], widget=forms.Select(attrs = {}), required = False, error_messages = {'required':'Workshop field is required.'}) training = forms.ChoiceField(choices = [('', '-- None --'),], widget=forms.Select(attrs = {}), required = False, error_messages = {'required':'Training field is required.'}) @@ -312,26 +312,50 @@ def __init__(self, *args, **kwargs): del kwargs["instance"] super(TestForm, self).__init__(*args, **kwargs) + # Limit columns loaded for test category choices + self.fields['test_category'].queryset = TestCategory.objects.filter(status=True).only('id', 'name') + def get_trainings_for_organiser(user) : - trainings = TrainingRequest.test_training.filter(training_planner__academic = user.organiser.academic, training_planner__organiser=user.organiser) + trainings = TrainingRequest.test_training.filter( + training_planner__academic = user.organiser.academic, + training_planner__organiser=user.organiser + ).select_related( + 'course', + 'course__foss', + 'course__course', + 'batch', + 'batch__department', + 'training_planner' + ) return trainings if user: - trainings = get_trainings_for_organiser(user) + trainings = get_trainings_for_organiser(user).filter(course__test=True) trchoices = [('', '-------')] for training in trainings: - if training.course.test: - trchoices.append((training.id, training.training_name())) + trchoices.append((training.id, training.training_name())) self.fields['training'].choices = trchoices - self.fields['invigilator'].queryset = Invigilator.objects.filter(academic = user.organiser.academic, status=1).exclude(user_id = user.id) + user_academic = user.organiser.academic + exclude_user_id = user.id + self.fields['invigilator'].queryset = ( + Invigilator.objects.filter(academic=user_academic, status=1) + .exclude(user_id=exclude_user_id) + .select_related('user') + ) if instance: - self.fields['invigilator'].queryset = Invigilator.objects.filter(academic = instance.organiser.academic, status=1).exclude(user_id = user.id) + instance_academic = instance.organiser.academic + exclude_user_id = user.id if user else instance.organiser.user_id + self.fields['invigilator'].queryset = ( + Invigilator.objects.filter(academic=instance_academic, status=1) + .exclude(user_id=exclude_user_id) + .select_related('user') + ) self.fields['invigilator'].initial = instance.invigilator self.fields['test_category'].initial = instance.test_category self.fields['tdate'].initial = str(instance.tdate) + " " + str(instance.ttime)[0:5] - if instance.test_category.id == 2: + if instance.test_category_id == 2: self.fields['training'].initial = instance.training_id class TrainingScanCopyForm(forms.Form): diff --git a/events/views.py b/events/views.py index 98561d668..b970ab827 100644 --- a/events/views.py +++ b/events/views.py @@ -1856,13 +1856,16 @@ def training_participant_ceritificate(request, wid, participant_id): @login_required def test_request(request, role, rid = None): ''' Test request by organiser ''' - user = request.user + # Prefetch organiser and academic state to avoid repeated lazy loads + user = request.user.__class__.objects.select_related( + 'organiser__academic__state' + ).get(pk=request.user.pk) if not (user.is_authenticated() and ( is_organiser(user) or is_resource_person(user) or is_event_manager(user))): raise PermissionDenied() context = {} form = TestForm(user = user) if rid: - t = Test.objects.get(pk = rid) + t = Test.objects.select_related('organiser', 'organiser__user', 'organiser__academic', 'organiser__academic__state', 'test_category', 'academic', 'academic__state').get(pk = rid) user = t.organiser.user form = TestForm(user = user, instance = t) context['instance'] = t @@ -1872,7 +1875,7 @@ def test_request(request, role, rid = None): dateTime = request.POST['tdate'].split(' ') t = Test() if rid: - t = Test.objects.get(pk = rid) + t = Test.objects.select_related('organiser', 'organiser__user', 'organiser__academic', 'organiser__academic__state', 'test_category', 'academic', 'academic__state').get(pk = rid) else: print("New Test.............") t.organiser_id = user.organiser.id @@ -1960,6 +1963,7 @@ def test_request(request, role, rid = None): context['status'] = 'request' context.update(csrf(request)) context['form'] = form + context['user'] = user return render(request, 'events/templates/test/form.html', context) @login_required