Skip to content

Commit 8fc14fd

Browse files
authored
perf: admin perf optimization for course-discovery (#4496)
1 parent 0151719 commit 8fc14fd

File tree

1 file changed

+114
-2
lines changed
  • course_discovery/apps/course_metadata

1 file changed

+114
-2
lines changed

course_discovery/apps/course_metadata/admin.py

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.conf import settings
44
from django.contrib import admin, messages
55
from django.contrib.admin.utils import model_ngettext
6+
from django.db.models import Prefetch
67
from django.db.utils import IntegrityError
78
from django.forms import CheckboxSelectMultiple, ModelForm
89
from django.http import HttpResponseRedirect
@@ -85,6 +86,9 @@ class SeatInline(admin.TabularInline):
8586
readonly_fields = ('_upgrade_deadline', )
8687
raw_id_fields = ('draft_version', 'currency')
8788

89+
def get_queryset(self, request):
90+
return super().get_queryset(request).select_related('draft_version', 'currency')
91+
8892

8993
class PositionInline(admin.TabularInline):
9094
model = Position
@@ -135,6 +139,10 @@ class CourseAdmin(DjangoObjectActions, SimpleHistoryAdmin):
135139
autocomplete_fields = ['canonical_course_run']
136140
change_actions = ('course_skills', 'refresh_course_skills')
137141

142+
def get_queryset(self, request):
143+
queryset = super().get_queryset(request)
144+
return queryset.select_related('canonical_course_run').prefetch_related('location_restriction')
145+
138146
def get_search_results(self, request, queryset, search_term):
139147
queryset, may_have_duplicates = super().get_search_results(request, queryset, search_term)
140148
if request.GET.get('app_label') == learner_pathway_app_name:
@@ -223,15 +231,18 @@ class CourseEditorAdmin(admin.ModelAdmin):
223231
@admin.register(CourseEntitlement)
224232
class CourseEntitlementAdmin(SimpleHistoryAdmin):
225233
list_display = ['course', 'get_course_key', 'mode', 'draft']
234+
raw_id_fields = ('course', 'draft_version',)
235+
search_fields = ['course__title', 'course__key']
226236

227237
@admin.display(
228238
description='Course key'
229239
)
230240
def get_course_key(self, obj):
231241
return obj.course.key
232242

233-
raw_id_fields = ('course', 'draft_version',)
234-
search_fields = ['course__title', 'course__key']
243+
def get_queryset(self, request):
244+
queryset = super().get_queryset(request)
245+
return queryset.select_related('course', 'mode', 'partner')
235246

236247

237248
@admin.register(Mode)
@@ -242,6 +253,7 @@ class ModeAdmin(admin.ModelAdmin):
242253
@admin.register(Track)
243254
class TrackAdmin(admin.ModelAdmin):
244255
list_display = ['mode', 'seat_type']
256+
list_select_related = ['seat_type', 'mode']
245257

246258

247259
@admin.register(CourseRunType)
@@ -287,6 +299,12 @@ class CourseRunAdmin(SimpleHistoryAdmin):
287299
save_error = False
288300
form = CourseRunAdminForm
289301

302+
def get_queryset(self, request):
303+
qs = super().get_queryset(request)
304+
return qs.select_related(
305+
'course', 'draft_version', 'language', 'type'
306+
)
307+
290308
def get_readonly_fields(self, request, obj=None):
291309
"""
292310
Make UUID field editable for draft if flag is enabled.
@@ -391,6 +409,30 @@ class ProgramAdmin(DjangoObjectActions, SimpleHistoryAdmin):
391409

392410
save_error = False
393411

412+
def get_queryset(self, request):
413+
queryset = super().get_queryset(request)
414+
queryset = queryset.select_related(
415+
'partner',
416+
'type'
417+
).prefetch_related(
418+
'courses',
419+
'authoring_organizations',
420+
'credit_backing_organizations',
421+
)
422+
return queryset
423+
424+
def formfield_for_foreignkey(self, db_field, request, **kwargs):
425+
"""
426+
Optimize ForeignKey dropdowns by customizing the queryset.
427+
"""
428+
if db_field.name == 'primary_subject_override':
429+
kwargs['queryset'] = Subject.objects.all()
430+
if db_field.name == 'level_type_override':
431+
kwargs['queryset'] = LevelType.objects.all()
432+
if db_field.name == 'type':
433+
kwargs['queryset'] = ProgramType.objects.all()
434+
return super().formfield_for_foreignkey(db_field, request, **kwargs)
435+
394436
def get_readonly_fields(self, request, obj=None):
395437
"""
396438
Make product_source field readonly if program obj is already created. In case a product without product_source
@@ -492,6 +534,15 @@ class PathwayAdmin(admin.ModelAdmin):
492534
def get_programs(self, obj):
493535
return [*obj.programs.all()]
494536

537+
def get_queryset(self, request):
538+
queryset = super().get_queryset(request)
539+
queryset = queryset.select_related('partner').prefetch_related(
540+
Prefetch('programs', queryset=Program.objects.prefetch_related(
541+
'courses__course_runs',
542+
))
543+
)
544+
return queryset
545+
495546

496547
@admin.register(ProgramType)
497548
class ProgramTypeAdmin(TranslatableAdmin):
@@ -538,6 +589,10 @@ class AdditionalPromoAreaAdmin(admin.ModelAdmin):
538589
list_display = ('title', 'description', 'courses')
539590
search_fields = ('description',)
540591

592+
def get_queryset(self, request):
593+
queryset = super().get_queryset(request)
594+
return queryset.prefetch_related('extra_description')
595+
541596
def courses(self, obj):
542597
return ', '.join([
543598
course.key for course in obj.extra_description.all()
@@ -549,6 +604,17 @@ class FactAdmin(admin.ModelAdmin):
549604
list_display = ('heading', 'blurb', 'courses')
550605
search_fields = ('heading', 'blurb',)
551606

607+
def get_queryset(self, request):
608+
queryset = super().get_queryset(request)
609+
queryset = queryset.prefetch_related(
610+
Prefetch(
611+
"related_course_additional_metadata",
612+
queryset=AdditionalMetadata.objects.prefetch_related("related_courses"),
613+
)
614+
)
615+
616+
return queryset
617+
552618
def courses(self, obj):
553619

554620
def _get_course_keys(additional_metadata_object):
@@ -564,6 +630,9 @@ class CertificateInfoAdmin(admin.ModelAdmin):
564630
list_display = ('heading', 'blurb', 'courses')
565631
search_fields = ('heading', 'blurb',)
566632

633+
def get_queryset(self, request):
634+
return super().get_queryset(request).prefetch_related('related_course_additional_metadata__related_courses')
635+
567636
def courses(self, obj):
568637

569638
def _get_course_keys(additional_metadata_object):
@@ -583,6 +652,17 @@ class AdditionalMetadataAdmin(admin.ModelAdmin):
583652
search_fields = ('external_identifier', 'external_url')
584653
list_filter = ('product_status', )
585654

655+
def get_queryset(self, request):
656+
queryset = super().get_queryset(request)
657+
return queryset.prefetch_related(
658+
'related_courses',
659+
'facts',
660+
).select_related(
661+
'taxi_form',
662+
'product_meta',
663+
'certificate_info',
664+
)
665+
586666
def courses(self, obj):
587667
return ', '.join([
588668
course.key for course in obj.related_courses.all()
@@ -643,6 +723,9 @@ class SubjectAdmin(TranslatableAdmin):
643723
readonly_fields = ('uuid',)
644724
search_fields = ('uuid', 'name', 'slug',)
645725

726+
def get_queryset(self, request):
727+
return super().get_queryset(request).select_related('partner').prefetch_related('translations')
728+
646729

647730
@admin.register(Topic)
648731
class TopicAdmin(TranslatableAdmin):
@@ -661,6 +744,12 @@ class PersonAdmin(admin.ModelAdmin):
661744
readonly_fields = ('uuid',)
662745
search_fields = ('uuid', 'salutation', 'family_name', 'given_name', 'slug',)
663746

747+
def get_queryset(self, request):
748+
return super().get_queryset(request).select_related(
749+
'partner',
750+
'bio_language',
751+
)
752+
664753

665754
@admin.register(Position)
666755
class PositionAdmin(admin.ModelAdmin):
@@ -697,6 +786,14 @@ class LevelTypeAdmin(SortableAdminMixin, TranslatableAdmin):
697786
search_fields = ('name_t',)
698787
fields = ('name_t',)
699788

789+
def get_queryset(self, request):
790+
return super().get_queryset(request).prefetch_related(
791+
Prefetch('translations', queryset=LevelTypeTranslation.objects.all(), to_attr='translated_names')
792+
)
793+
794+
def name_t(self, obj):
795+
return obj.translated_names[0].name_t if obj.translated_names else obj.name
796+
700797

701798
class CurriculumProgramMembershipInline(admin.TabularInline):
702799
model = CurriculumProgramMembership
@@ -782,11 +879,17 @@ class IconTextPairingInline(admin.StackedInline):
782879
class DegreeDeadlineAdmin(admin.ModelAdmin):
783880
list_display = ('degree', 'semester', 'name', 'date', 'time')
784881

882+
def get_queryset(self, request):
883+
return super().get_queryset(request).select_related('degree')
884+
785885

786886
@admin.register(DegreeCost)
787887
class DegreeCostAdmin(admin.ModelAdmin):
788888
list_display = ('degree', 'description', 'amount')
789889

890+
def get_queryset(self, request):
891+
return super().get_queryset(request).select_related('degree')
892+
790893

791894
class DegreeDeadlineInlineAdmin(admin.StackedInline):
792895
model = DegreeDeadline
@@ -806,6 +909,9 @@ class DegreeAdditionalMetadataInlineAdmin(admin.StackedInline):
806909
class DegreeAdditionalMetadataAdmin(admin.ModelAdmin):
807910
list_display = ('degree', 'external_url', 'external_identifier', 'organic_url')
808911

912+
def get_queryset(self, request):
913+
return super().get_queryset(request).select_related('degree')
914+
809915

810916
@admin.register(Specialization)
811917
class SpecializationAdmin(admin.ModelAdmin):
@@ -843,6 +949,9 @@ class DegreeAdmin(admin.ModelAdmin):
843949
)
844950
actions = ['publish_degrees', 'unpublish_degrees', 'display_degrees_on_org_page', 'hide_degrees_on_org_page']
845951

952+
def get_queryset(self, request):
953+
return super().get_queryset(request).prefetch_related('additional_metadata')
954+
846955
def change_degree_status(self, request, queryset, status):
847956
"""
848957
Changes the status of a degree.
@@ -1052,6 +1161,9 @@ class RestrictedCourseRunAdmin(admin.ModelAdmin):
10521161
list_display = ['course_run', 'restriction_type']
10531162
search_fields = ['course_run__key', 'restriction_type']
10541163

1164+
def get_queryset(self, request):
1165+
return super().get_queryset(request).select_related('course_run__course')
1166+
10551167

10561168
class CourseReviewAdmin(admin.ModelAdmin):
10571169
"""

0 commit comments

Comments
 (0)