3
3
from django .conf import settings
4
4
from django .contrib import admin , messages
5
5
from django .contrib .admin .utils import model_ngettext
6
+ from django .db .models import Prefetch
6
7
from django .db .utils import IntegrityError
7
8
from django .forms import CheckboxSelectMultiple , ModelForm
8
9
from django .http import HttpResponseRedirect
@@ -85,6 +86,9 @@ class SeatInline(admin.TabularInline):
85
86
readonly_fields = ('_upgrade_deadline' , )
86
87
raw_id_fields = ('draft_version' , 'currency' )
87
88
89
+ def get_queryset (self , request ):
90
+ return super ().get_queryset (request ).select_related ('draft_version' , 'currency' )
91
+
88
92
89
93
class PositionInline (admin .TabularInline ):
90
94
model = Position
@@ -135,6 +139,10 @@ class CourseAdmin(DjangoObjectActions, SimpleHistoryAdmin):
135
139
autocomplete_fields = ['canonical_course_run' ]
136
140
change_actions = ('course_skills' , 'refresh_course_skills' )
137
141
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
+
138
146
def get_search_results (self , request , queryset , search_term ):
139
147
queryset , may_have_duplicates = super ().get_search_results (request , queryset , search_term )
140
148
if request .GET .get ('app_label' ) == learner_pathway_app_name :
@@ -223,15 +231,18 @@ class CourseEditorAdmin(admin.ModelAdmin):
223
231
@admin .register (CourseEntitlement )
224
232
class CourseEntitlementAdmin (SimpleHistoryAdmin ):
225
233
list_display = ['course' , 'get_course_key' , 'mode' , 'draft' ]
234
+ raw_id_fields = ('course' , 'draft_version' ,)
235
+ search_fields = ['course__title' , 'course__key' ]
226
236
227
237
@admin .display (
228
238
description = 'Course key'
229
239
)
230
240
def get_course_key (self , obj ):
231
241
return obj .course .key
232
242
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' )
235
246
236
247
237
248
@admin .register (Mode )
@@ -242,6 +253,7 @@ class ModeAdmin(admin.ModelAdmin):
242
253
@admin .register (Track )
243
254
class TrackAdmin (admin .ModelAdmin ):
244
255
list_display = ['mode' , 'seat_type' ]
256
+ list_select_related = ['seat_type' , 'mode' ]
245
257
246
258
247
259
@admin .register (CourseRunType )
@@ -287,6 +299,12 @@ class CourseRunAdmin(SimpleHistoryAdmin):
287
299
save_error = False
288
300
form = CourseRunAdminForm
289
301
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
+
290
308
def get_readonly_fields (self , request , obj = None ):
291
309
"""
292
310
Make UUID field editable for draft if flag is enabled.
@@ -391,6 +409,30 @@ class ProgramAdmin(DjangoObjectActions, SimpleHistoryAdmin):
391
409
392
410
save_error = False
393
411
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
+
394
436
def get_readonly_fields (self , request , obj = None ):
395
437
"""
396
438
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):
492
534
def get_programs (self , obj ):
493
535
return [* obj .programs .all ()]
494
536
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
+
495
546
496
547
@admin .register (ProgramType )
497
548
class ProgramTypeAdmin (TranslatableAdmin ):
@@ -538,6 +589,10 @@ class AdditionalPromoAreaAdmin(admin.ModelAdmin):
538
589
list_display = ('title' , 'description' , 'courses' )
539
590
search_fields = ('description' ,)
540
591
592
+ def get_queryset (self , request ):
593
+ queryset = super ().get_queryset (request )
594
+ return queryset .prefetch_related ('extra_description' )
595
+
541
596
def courses (self , obj ):
542
597
return ', ' .join ([
543
598
course .key for course in obj .extra_description .all ()
@@ -549,6 +604,17 @@ class FactAdmin(admin.ModelAdmin):
549
604
list_display = ('heading' , 'blurb' , 'courses' )
550
605
search_fields = ('heading' , 'blurb' ,)
551
606
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
+
552
618
def courses (self , obj ):
553
619
554
620
def _get_course_keys (additional_metadata_object ):
@@ -564,6 +630,9 @@ class CertificateInfoAdmin(admin.ModelAdmin):
564
630
list_display = ('heading' , 'blurb' , 'courses' )
565
631
search_fields = ('heading' , 'blurb' ,)
566
632
633
+ def get_queryset (self , request ):
634
+ return super ().get_queryset (request ).prefetch_related ('related_course_additional_metadata__related_courses' )
635
+
567
636
def courses (self , obj ):
568
637
569
638
def _get_course_keys (additional_metadata_object ):
@@ -583,6 +652,17 @@ class AdditionalMetadataAdmin(admin.ModelAdmin):
583
652
search_fields = ('external_identifier' , 'external_url' )
584
653
list_filter = ('product_status' , )
585
654
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
+
586
666
def courses (self , obj ):
587
667
return ', ' .join ([
588
668
course .key for course in obj .related_courses .all ()
@@ -643,6 +723,9 @@ class SubjectAdmin(TranslatableAdmin):
643
723
readonly_fields = ('uuid' ,)
644
724
search_fields = ('uuid' , 'name' , 'slug' ,)
645
725
726
+ def get_queryset (self , request ):
727
+ return super ().get_queryset (request ).select_related ('partner' ).prefetch_related ('translations' )
728
+
646
729
647
730
@admin .register (Topic )
648
731
class TopicAdmin (TranslatableAdmin ):
@@ -661,6 +744,12 @@ class PersonAdmin(admin.ModelAdmin):
661
744
readonly_fields = ('uuid' ,)
662
745
search_fields = ('uuid' , 'salutation' , 'family_name' , 'given_name' , 'slug' ,)
663
746
747
+ def get_queryset (self , request ):
748
+ return super ().get_queryset (request ).select_related (
749
+ 'partner' ,
750
+ 'bio_language' ,
751
+ )
752
+
664
753
665
754
@admin .register (Position )
666
755
class PositionAdmin (admin .ModelAdmin ):
@@ -697,6 +786,14 @@ class LevelTypeAdmin(SortableAdminMixin, TranslatableAdmin):
697
786
search_fields = ('name_t' ,)
698
787
fields = ('name_t' ,)
699
788
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
+
700
797
701
798
class CurriculumProgramMembershipInline (admin .TabularInline ):
702
799
model = CurriculumProgramMembership
@@ -782,11 +879,17 @@ class IconTextPairingInline(admin.StackedInline):
782
879
class DegreeDeadlineAdmin (admin .ModelAdmin ):
783
880
list_display = ('degree' , 'semester' , 'name' , 'date' , 'time' )
784
881
882
+ def get_queryset (self , request ):
883
+ return super ().get_queryset (request ).select_related ('degree' )
884
+
785
885
786
886
@admin .register (DegreeCost )
787
887
class DegreeCostAdmin (admin .ModelAdmin ):
788
888
list_display = ('degree' , 'description' , 'amount' )
789
889
890
+ def get_queryset (self , request ):
891
+ return super ().get_queryset (request ).select_related ('degree' )
892
+
790
893
791
894
class DegreeDeadlineInlineAdmin (admin .StackedInline ):
792
895
model = DegreeDeadline
@@ -806,6 +909,9 @@ class DegreeAdditionalMetadataInlineAdmin(admin.StackedInline):
806
909
class DegreeAdditionalMetadataAdmin (admin .ModelAdmin ):
807
910
list_display = ('degree' , 'external_url' , 'external_identifier' , 'organic_url' )
808
911
912
+ def get_queryset (self , request ):
913
+ return super ().get_queryset (request ).select_related ('degree' )
914
+
809
915
810
916
@admin .register (Specialization )
811
917
class SpecializationAdmin (admin .ModelAdmin ):
@@ -843,6 +949,9 @@ class DegreeAdmin(admin.ModelAdmin):
843
949
)
844
950
actions = ['publish_degrees' , 'unpublish_degrees' , 'display_degrees_on_org_page' , 'hide_degrees_on_org_page' ]
845
951
952
+ def get_queryset (self , request ):
953
+ return super ().get_queryset (request ).prefetch_related ('additional_metadata' )
954
+
846
955
def change_degree_status (self , request , queryset , status ):
847
956
"""
848
957
Changes the status of a degree.
@@ -1052,6 +1161,9 @@ class RestrictedCourseRunAdmin(admin.ModelAdmin):
1052
1161
list_display = ['course_run' , 'restriction_type' ]
1053
1162
search_fields = ['course_run__key' , 'restriction_type' ]
1054
1163
1164
+ def get_queryset (self , request ):
1165
+ return super ().get_queryset (request ).select_related ('course_run__course' )
1166
+
1055
1167
1056
1168
class CourseReviewAdmin (admin .ModelAdmin ):
1057
1169
"""
0 commit comments