88from drf_spectacular .utils import extend_schema
99from rest_framework import viewsets
1010from rest_framework .pagination import PageNumberPagination
11+ from rest_framework .permissions import IsAuthenticatedOrReadOnly
1112
1213from courses .models import (
1314 Course ,
@@ -53,12 +54,33 @@ class Meta:
5354 model = Program
5455 fields = ["id" , "live" , "readable_id" , "page__live" , "org_id" ]
5556
56- def __init__ (self , * args , request_user = None , ** kwargs ):
57- self .user = request_user
57+ def __init__ (self , * args , ** kwargs ):
5858 super ().__init__ (* args , ** kwargs )
5959
60+ @property
61+ def qs (self ):
62+ """If the request isn't explicitly filtering on org_id, exclude contracted courses."""
63+
64+ if "org_id" not in getattr (self .request , "GET" , {}):
65+ program_requirements_with_contract_runs = ProgramRequirement .objects .filter (
66+ node_type = ProgramRequirementNodeType .COURSE ,
67+ course__courseruns__b2b_contract__isnull = False ,
68+ program_id = OuterRef ("pk" ),
69+ )
70+ return (
71+ super ()
72+ .qs .annotate (
73+ has_contracted_courses = Exists (
74+ program_requirements_with_contract_runs
75+ )
76+ )
77+ .filter (has_contracted_courses = False )
78+ )
79+
80+ return super ().qs
81+
6082 def filter_by_org_id (self , queryset , _ , org_id ):
61- if user_has_org_access (self .user , org_id ):
83+ if self . request and user_has_org_access (self . request .user , org_id ):
6284 program_requirements_with_contract_runs = ProgramRequirement .objects .filter (
6385 node_type = ProgramRequirementNodeType .COURSE ,
6486 course__courseruns__b2b_contract__organization_id = org_id ,
@@ -82,29 +104,27 @@ def filter_by_org_id(self, queryset, _, org_id):
82104class ProgramViewSet (viewsets .ReadOnlyModelViewSet ):
83105 """API viewset for Programs"""
84106
85- permission_classes = []
107+ permission_classes = [IsAuthenticatedOrReadOnly ]
86108 serializer_class = ProgramSerializer
87109 pagination_class = Pagination
88110 filter_backends = [DjangoFilterBackend ]
89111 filterset_class = ProgramFilterSet
90112
91113 def get_queryset (self ):
114+ """Get the queryset"""
92115 return Program .objects .order_by ("title" ).prefetch_related ("departments" )
93116
94- def get_filterset_kwargs (self ):
95- kwargs = super ().get_filterset_kwargs ()
96- kwargs ["request_user" ] = self .request .user
97- return kwargs
98-
99117 @extend_schema (
100118 operation_id = "programs_retrieve_v2" ,
101119 description = "API view set for Programs - v2" ,
102120 )
103121 def retrieve (self , request , * args , ** kwargs ):
122+ """Retrieve a specific program."""
104123 return super ().retrieve (request , * args , ** kwargs )
105124
106125 @extend_schema (operation_id = "programs_list_v2" , description = "List Programs - v2" )
107126 def list (self , request , * args , ** kwargs ):
127+ """List the available programs."""
108128 return super ().list (request , * args , ** kwargs )
109129
110130
0 commit comments