@@ -562,6 +562,7 @@ class UpdateQuiz(BaseModel):
562562 deadline_days : Optional [int ] = Field (
563563 ge = MIN_QUIZ_DEADLINE , le = MAX_QUIZ_DEADLINE , examples = [14 ], default = None
564564 )
565+ is_blocking : Optional [bool ] = None
565566
566567 model_config = ConfigDict (extra = "forbid" )
567568
@@ -576,6 +577,7 @@ class QuizCreate(BaseModel):
576577 questions : list [QuestionCreate ] = Field (min_length = 1 )
577578 type : Literal ["quiz" ] = "quiz"
578579 limited_attempts : bool = Field (default = True , examples = [True ])
580+ is_blocking : bool = Field (default = True , examples = [True ])
579581
580582
581583class QuizResponse (BaseModel ):
@@ -586,6 +588,7 @@ class QuizResponse(BaseModel):
586588 deadline_days : int = Field (ge = MIN_QUIZ_DEADLINE , le = MAX_QUIZ_DEADLINE )
587589 questions : Any # Will be converted to list in field_serializer
588590 limited_attempts : bool
591+ is_blocking : bool
589592
590593 @field_serializer ("questions" )
591594 def serialize_questions (self , questions : Any ) -> list [dict ]:
@@ -672,6 +675,7 @@ class QuizSubmitedEvent(BaseModel):
672675 score : int
673676 is_passed : bool
674677 attempt_number : int
678+ is_practice : bool
675679
676680
677681class ContentSentEvent (BaseModel ):
@@ -715,7 +719,7 @@ def from_django_model(enrollment: Enrollment) -> "EnrollmentResponse":
715719 event_data = None ,
716720 )
717721 )
718- for delivery in enrollment .content_deliveries .all (): # type: ignore[attr-defined]
722+ for delivery in enrollment .content_deliveries .all (). order_by ( "id" ) : # type: ignore[attr-defined]
719723 schedule_no = 0
720724 for schedule in delivery .delivery_schedules .filter (
721725 status = DeliveryStatus .DELIVERED
@@ -740,26 +744,34 @@ def from_django_model(enrollment: Enrollment) -> "EnrollmentResponse":
740744 "submitted_at"
741745 )
742746 attempt = None
743- if schedule_no == 1 :
744- attempt = quiz_attempts .first ()
747+ if delivery .course_content .quiz .is_blocking : # type: ignore[union-attr]
748+ if schedule_no == 1 :
749+ attempts = [quiz_attempts .first ()]
750+ attempt_number = 1
751+ elif schedule_no > 1 :
752+ attempt_number = schedule_no
753+ attempts = list (quiz_attempts [1 :])
754+ else :
745755 attempt_number = 1
746- elif schedule_no > 1 :
747- attempt_number = schedule_no
748- attempt = quiz_attempts [attempt_number - 1 :].first ()
749- if attempt :
750- events .append (
751- Event (
752- type = EventType .QUIZ_SUBMITED ,
753- timestamp = attempt .submitted_at ,
754- event_data = QuizSubmitedEvent (
755- quiz_id = delivery .course_content .quiz .id , # type: ignore[union-attr]
756- quiz_title = delivery .course_content .quiz .title , # type: ignore[union-attr]
757- score = attempt .score ,
758- is_passed = attempt .is_passed ,
759- attempt_number = attempt_number ,
760- ),
756+ attempts = list (quiz_attempts )
757+ if attempts :
758+ for attempt in [i for i in attempts if i is not None ]: # type: ignore[union-attr]
759+ events .append (
760+ Event (
761+ type = EventType .QUIZ_SUBMITED ,
762+ timestamp = attempt .submitted_at ,
763+ event_data = QuizSubmitedEvent (
764+ quiz_id = delivery .course_content .quiz .id , # type: ignore[union-attr]
765+ quiz_title = delivery .course_content .quiz .title , # type: ignore[union-attr]
766+ score = attempt .score ,
767+ is_passed = attempt .is_passed ,
768+ attempt_number = attempt_number ,
769+ is_practice = delivery .course_content .quiz .is_blocking # type: ignore[union-attr]
770+ is False , # type: ignore[union-attr]
771+ ),
772+ )
761773 )
762- )
774+ attempt_number += 1
763775 if (
764776 enrollment .status == EnrollmentStatus .COMPLETED
765777 and enrollment .final_state_at
@@ -831,6 +843,7 @@ def to_django_model(self, course: Course) -> CourseContent:
831843 selection_strategy = self .content .selection_strategy .value , # type: ignore[misc]
832844 deadline_days = self .content .deadline_days , # type: ignore[misc]
833845 limited_attempts = self .content .limited_attempts , # type: ignore[misc]
846+ is_blocking = self .content .is_blocking , # type: ignore[misc]
834847 )
835848 quiz .save ()
836849 for question_data in self .content .questions :
@@ -910,6 +923,7 @@ class CourseContentSummaryResponse(BaseModel):
910923 is_published : bool
911924 type : str
912925 limited_attempts : Optional [bool ] = None
926+ is_blocking : Optional [bool ] = None
913927
914928 @field_serializer ("waiting_period" )
915929 def serialize_waiting_period (self , waiting_period : int ) -> dict :
0 commit comments