22
33from django .db import DatabaseError
44from django .http import JsonResponse
5- from rest_framework .views import APIView
5+ from rest_framework .decorators import action
66from rest_framework .request import Request
7+ from rest_framework .response import Response
8+ from rest_framework .viewsets import ModelViewSet
79
810from langpro_annotator .logger import logger
9- from problem .problem_details import get_filters , get_related_problem_ids
11+ from problem .problem_details import (
12+ get_filters ,
13+ get_related_problem_ids ,
14+ )
1015from problem .models import KnowledgeBase , Problem , Sentence
11- from problem .serializers import ProblemInputSerializer
12-
13-
14- @dataclass
15- class ProblemResponse :
16- problem : Problem | None = None
17- index : int | None = None
18- error : str | None = None
19-
20- first : int | None = None
21- previous : int | None = None
22- next : int | None = None
23- last : int | None = None
24- total : int | None = None
25-
26- def json_response (self , status = 200 ) -> JsonResponse :
27- return JsonResponse (
28- {
29- "index" : self .index ,
30- "problem" : self .problem .serialize () if self .problem else None ,
31- "error" : self .error ,
32- "firstProblemId" : self .first ,
33- "previousProblemId" : self .previous ,
34- "nextProblemId" : self .next ,
35- "lastProblemId" : self .last ,
36- "totalProblems" : self .total if self .total is not None else 0 ,
37- },
38- status = status ,
39- )
40-
16+ from problem .serializers import ProblemSerializer
4117
4218@dataclass
4319class SaveProblemResponse :
@@ -48,23 +24,54 @@ def json_response(self, status=200) -> JsonResponse:
4824 return JsonResponse (asdict (self ), status = status )
4925
5026
51- class ProblemView (APIView ):
52- def get (self , request : Request , problem_id : int | None = None ) -> JsonResponse :
27+ class ProblemView (ModelViewSet ):
28+ queryset = Problem .objects .all ()
29+ serializer_class = ProblemSerializer
30+
31+ def list (self , request : Request ) -> Response :
32+ """
33+ Lists all Problems in the database, with optional filtering.
34+ """
35+ filters = get_filters (request .query_params )
36+
37+ qs = self .get_queryset ()
38+
39+ if filters is not None :
40+ qs = qs .filter (filters )
41+
42+ serializer = self .get_serializer (qs , many = True )
43+ return Response (serializer .data , status = 200 )
44+
45+
46+ @action (detail = False , methods = ['get' ], url_path = 'first' )
47+ def first (self , request : Request ) -> Response :
48+ """
49+ Retrieves the first problem from the queryset.
50+ """
51+ return self ._get_problem_response (request , pk = None )
52+
53+ def retrieve (self , request : Request , pk : int | None = None ) -> Response :
54+ """
55+ Retrieves the requested Problem by ID.
56+ """
57+ return self ._get_problem_response (request , pk = pk )
58+
59+ def _get_problem_response (self , request : Request , pk : int | None ) -> Response :
5360 """
54- If a Problem ID is provided, retrieves the requested Problem .
55- Otherwise, simply returns the first problem of the QS .
61+ Helper method to build the problem response .
62+ If pk is provided, retrieves that problem; otherwise returns the first problem .
5663 """
5764 filters = get_filters (request .query_params )
5865
59- qs = Problem . objects . all ()
66+ qs = self . get_queryset ()
6067
6168 if filters is not None :
6269 qs = qs .filter (filters )
6370
6471 problem = None
65- if problem_id is not None :
72+ if pk is not None :
6673 try :
67- problem = qs .get (id = problem_id )
74+ problem = qs .get (id = pk )
6875 except Problem .DoesNotExist :
6976 # The selected problem may not be part of the selected filters.
7077 # In that case, we simply take the first problem from the queryset.
@@ -74,17 +81,19 @@ def get(self, request: Request, problem_id: int | None = None) -> JsonResponse:
7481 problem = qs .first ()
7582
7683 problem_index = problem .get_index (qs ) if problem else None
77- related_problem_ids = get_related_problem_ids (qs , problem_id )
78-
79- return ProblemResponse (
80- problem = problem ,
81- index = problem_index ,
82- first = related_problem_ids .first ,
83- previous = related_problem_ids .previous ,
84- next = related_problem_ids .next ,
85- last = related_problem_ids .last ,
86- total = related_problem_ids .total ,
87- ).json_response (status = 200 )
84+ related_problem_ids = get_related_problem_ids (qs , pk )
85+
86+ serializer = self .get_serializer (problem )
87+
88+ return Response ({
89+ "problem" : serializer .data ,
90+ "index" : problem_index ,
91+ "first" : related_problem_ids .first ,
92+ "previous" : related_problem_ids .previous ,
93+ "next" : related_problem_ids .next ,
94+ "last" : related_problem_ids .last ,
95+ "total" : related_problem_ids .total ,
96+ }, status = 200 )
8897
8998 def post (self , request : Request , problem_id : int | None = None ) -> JsonResponse :
9099 """
0 commit comments