4
4
from rest_framework .mixins import ListModelMixin , RetrieveModelMixin , UpdateModelMixin
5
5
from rest_framework .response import Response
6
6
from rest_framework .viewsets import GenericViewSet
7
+ from django .db .models import OuterRef , Subquery
7
8
8
- from .serializers import AssignmentViewSetSerializer , AssignmentInstrumentSerializer , AssignmentSerializer
9
+ from .serializers import (
10
+ AssignmentViewSetSerializer ,
11
+ AssignmentInstrumentSerializer ,
12
+ AssignmentSerializer ,
13
+ )
9
14
from teleband .assignments .api .serializers import ActivitySerializer , PiecePlanSerializer
10
15
from teleband .musics .api .serializers import PartTranspositionSerializer
11
16
@@ -29,14 +34,22 @@ class ActivityViewSet(RetrieveModelMixin, ListModelMixin, GenericViewSet):
29
34
permission_classes = [IsTeacher ]
30
35
31
36
def get_queryset (self ):
32
- return self .queryset .filter (
33
- pk__in = Assignment .objects .filter (
34
- enrollment__course__slug = self .kwargs ["course_slug_slug" ]
37
+ # Define a subquery to get the first assignment for each activity
38
+ distinct_activity_assignments = (
39
+ Assignment .objects .filter (
40
+ enrollment__course__slug = self .kwargs ["course_slug_slug" ],
41
+ activity = OuterRef ("id" ),
35
42
)
36
- .distinct ( "activity " )
37
- .values_list ( "pk" , flat = True )
43
+ .order_by ( "id" , "pk " )
44
+ .values ( "activity_id" )[: 1 ]
38
45
)
39
46
47
+ # Use the subquery to filter the main queryset
48
+ queryset = self .queryset .filter (pk__in = Subquery (distinct_activity_assignments ))
49
+
50
+ return queryset
51
+
52
+
40
53
class AssignmentViewSet (
41
54
RetrieveModelMixin , UpdateModelMixin , ListModelMixin , GenericViewSet
42
55
):
@@ -71,16 +84,36 @@ def get_queryset(self):
71
84
role = self .request .user .enrollment_set .get (course = course ).role
72
85
73
86
if role .name == "Student" :
74
- return Assignment .objects .filter (
75
- enrollment__course = course , enrollment__user = self .request .user
76
- ).select_related ("activity" , "instrument" , "piece" , "activity__part_type" , "instrument__transposition" , "group" ).prefetch_related ("submissions" )
87
+ return (
88
+ Assignment .objects .filter (
89
+ enrollment__course = course , enrollment__user = self .request .user
90
+ )
91
+ .select_related (
92
+ "activity" ,
93
+ "instrument" ,
94
+ "piece" ,
95
+ "activity__part_type" ,
96
+ "instrument__transposition" ,
97
+ "group" ,
98
+ )
99
+ .prefetch_related ("submissions" )
100
+ )
77
101
if role .name == "Teacher" :
78
- return Assignment .objects .filter (enrollment__course = course ).select_related ("activity" , "instrument" , "piece" , "activity__part_type" , "instrument__transposition" , "group" )
102
+ return Assignment .objects .filter (enrollment__course = course ).select_related (
103
+ "activity" ,
104
+ "instrument" ,
105
+ "piece" ,
106
+ "activity__part_type" ,
107
+ "instrument__transposition" ,
108
+ "group" ,
109
+ )
79
110
80
111
def list (self , request , * args , ** kwargs ):
81
112
assignments = self .get_queryset ()
82
113
83
- serialized = AssignmentViewSetSerializer (assignments , context = {'request' : request }, many = True )
114
+ serialized = AssignmentViewSetSerializer (
115
+ assignments , context = {"request" : request }, many = True
116
+ )
84
117
85
118
grouped = defaultdict (list )
86
119
for assignment in serialized .data :
@@ -101,24 +134,24 @@ def list(self, request, *args, **kwargs):
101
134
}
102
135
103
136
# FIXME: this should respect order from server/pieceplan and mayeb do this as a backup?
104
- orderFromActivityType = lambda a : ordering [a [' activity_type_name' ].split ()[0 ]]
137
+ orderFromActivityType = lambda a : ordering [a [" activity_type_name" ].split ()[0 ]]
105
138
for pieceplan in grouped :
106
139
grouped [pieceplan ].sort (key = orderFromActivityType )
107
140
108
141
return Response (grouped )
109
142
110
143
111
- class PiecePlanViewSet (
112
- RetrieveModelMixin , ListModelMixin , GenericViewSet
113
- ):
144
+ class PiecePlanViewSet (RetrieveModelMixin , ListModelMixin , GenericViewSet ):
114
145
serializer_class = PiecePlanSerializer
115
146
queryset = PiecePlan .objects .prefetch_related ("piece" )
116
147
lookup_field = "id"
117
148
permission_classes = [IsTeacher ]
118
149
119
150
def get_queryset (self ):
120
151
course = Course .objects .get (slug = self .kwargs ["course_slug_slug" ])
121
- return PiecePlan .objects .filter (curriculum__course = course ).prefetch_related ("piece" )
152
+ return PiecePlan .objects .filter (curriculum__course = course ).prefetch_related (
153
+ "piece"
154
+ )
122
155
123
156
# def get_serializer_class(self):
124
157
# if self.action == "create":
0 commit comments