@@ -466,7 +466,10 @@ def update_or_create_grade(cls, **params):
466466 Wrapper for objects.update_or_create.
467467 """
468468 cls ._prepare_params (params )
469- VisibleBlocks .cached_get_or_create (params ['user_id' ], params ['visible_blocks' ])
469+ # Capture the BlockRecordList before it's removed from params below, so the
470+ # event can be emitted without extra queries on grade.visible_blocks
471+ visible_blocks = params ['visible_blocks' ]
472+ VisibleBlocks .cached_get_or_create (params ['user_id' ], visible_blocks )
470473 cls ._prepare_params_visible_blocks_id (params )
471474
472475 # TODO: do we NEED to pop these?
@@ -487,7 +490,7 @@ def update_or_create_grade(cls, **params):
487490 grade .save ()
488491
489492 cls ._emit_grade_calculated_event (grade )
490- cls ._emit_openedx_persistent_subsection_grade_changed_event (grade )
493+ cls ._emit_openedx_persistent_subsection_grade_changed_event (grade , visible_blocks )
491494 return grade
492495
493496 @classmethod
@@ -501,16 +504,17 @@ def bulk_create_grades(cls, grade_params_iter, user_id, course_key):
501504 PersistentSubsectionGradeOverride .prefetch (user_id , course_key )
502505
503506 list (map (cls ._prepare_params , grade_params_iter ))
504- VisibleBlocks .bulk_get_or_create (
505- user_id , course_key , [params ['visible_blocks' ] for params in grade_params_iter ]
506- )
507+ # Capture the BlockRecordLists (in order) before they're removed from params below,
508+ # so events can be emitted without extra queries on grade.visible_blocks
509+ visible_blocks_list = [params ['visible_blocks' ] for params in grade_params_iter ]
510+ VisibleBlocks .bulk_get_or_create (user_id , course_key , visible_blocks_list )
507511 list (map (cls ._prepare_params_visible_blocks_id , grade_params_iter ))
508512
509513 grades = [PersistentSubsectionGrade (** params ) for params in grade_params_iter ]
510514 grades = cls .objects .bulk_create (grades )
511- for grade in grades :
515+ for grade , visible_blocks in zip ( grades , visible_blocks_list , strict = True ) :
512516 cls ._emit_grade_calculated_event (grade )
513- cls ._emit_openedx_persistent_subsection_grade_changed_event (grade )
517+ cls ._emit_openedx_persistent_subsection_grade_changed_event (grade , visible_blocks )
514518 return grades
515519
516520 @classmethod
@@ -541,7 +545,7 @@ def _emit_grade_calculated_event(grade):
541545 events .subsection_grade_calculated (grade )
542546
543547 @staticmethod
544- def _emit_openedx_persistent_subsection_grade_changed_event (grade ):
548+ def _emit_openedx_persistent_subsection_grade_changed_event (grade , visible_blocks ):
545549 """
546550 When called emits an event when a persistent subsection grade is created or updated.
547551 """
@@ -557,15 +561,15 @@ def _emit_openedx_persistent_subsection_grade_changed_event(grade):
557561 exc_info = True ,
558562 )
559563
560- visible_blocks = [
564+ xblocks_scoring_data = [
561565 XBlockWithScoringData (
562566 usage_key = block .locator ,
563567 block_type = block .locator .block_type ,
564568 graded = block .graded ,
565569 raw_possible = block .raw_possible ,
566570 weight = block .weight ,
567571 )
568- for block in grade . visible_blocks . blocks
572+ for block in visible_blocks
569573 ]
570574
571575 PERSISTENT_SUBSECTION_GRADE_CHANGED .send_event (
@@ -582,7 +586,7 @@ def _emit_openedx_persistent_subsection_grade_changed_event(grade):
582586 weighted_total_earned = grade .earned_all ,
583587 weighted_total_possible = grade .possible_all ,
584588 first_attempted = grade .first_attempted ,
585- visible_blocks = visible_blocks ,
589+ visible_blocks = xblocks_scoring_data ,
586590 visible_blocks_hash = str (grade .visible_blocks_id ),
587591 )
588592 )
0 commit comments