fix: certificate generation without Persistent Grades
Fix for an error related to endless recursion Dev Notes: The student gets the passing grade -> CourseGradeFactory sends the `COURSE_GRADE_NOW_PASSED` signal after the grade calculation -> `listen_for_passing_grade` receives the signal and calls `generate_certificate_task` -> `generate_certificate_task` calls `_generate_regular_certificate_task` -> `_generate_regular_certificate_task` trying to get grade by calling the `_get_course_grade` -> `_get_course_grade` calls `CourseGradeFactory().read()` but I have persistent grades off, so actually that ends with `CourseGradeFactory().update()` -> `CourseGradeFactory().update()` sends the `COURSE_GRADE_NOW_PASSED` And so on
This commit is contained in:
committed by
Eugene Dyudyunov
parent
56cef9cb6a
commit
c4bc6e29ea
@@ -72,7 +72,7 @@ def _generate_regular_certificate_task(user, course_key, generation_mode=None, d
|
||||
eligible and a certificate can be generated.
|
||||
"""
|
||||
enrollment_mode = _get_enrollment_mode(user, course_key)
|
||||
course_grade = _get_course_grade(user, course_key)
|
||||
course_grade = _get_course_grade(user, course_key, send_grade_signals=False)
|
||||
if _can_generate_regular_certificate(user, course_key, enrollment_mode, course_grade):
|
||||
return _generate_certificate_task(user=user, course_key=course_key, enrollment_mode=enrollment_mode,
|
||||
course_grade=course_grade, generation_mode=generation_mode,
|
||||
@@ -377,11 +377,11 @@ def _get_grade_value(course_grade):
|
||||
return ''
|
||||
|
||||
|
||||
def _get_course_grade(user, course_key):
|
||||
def _get_course_grade(user, course_key, send_grade_signals=False):
|
||||
"""
|
||||
Get the user's course grade in this course run. Note that this may be None.
|
||||
"""
|
||||
return CourseGradeFactory().read(user, course_key=course_key)
|
||||
return CourseGradeFactory().read(user, course_key=course_key, send_grade_signals=send_grade_signals)
|
||||
|
||||
|
||||
def _get_enrollment_mode(user, course_key):
|
||||
|
||||
@@ -33,6 +33,7 @@ class CourseGradeFactory:
|
||||
course_structure=None,
|
||||
course_key=None,
|
||||
create_if_needed=True,
|
||||
send_grade_signals=True,
|
||||
):
|
||||
"""
|
||||
Returns the CourseGrade for the given user in the course.
|
||||
@@ -51,7 +52,7 @@ class CourseGradeFactory:
|
||||
if assume_zero_if_absent(course_data.course_key):
|
||||
return self._create_zero(user, course_data)
|
||||
elif create_if_needed:
|
||||
return self._update(user, course_data)
|
||||
return self._update(user, course_data, send_grade_signals=send_grade_signals)
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -160,13 +161,16 @@ class CourseGradeFactory:
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _update(user, course_data, force_update_subsections=False):
|
||||
def _update(user, course_data, force_update_subsections=False, send_grade_signals=True):
|
||||
"""
|
||||
Computes, saves, and returns a CourseGrade object for the
|
||||
given user and course.
|
||||
Sends a COURSE_GRADE_CHANGED signal to listeners and
|
||||
COURSE_GRADE_NOW_PASSED if learner has passed course or
|
||||
COURSE_GRADE_NOW_FAILED if learner is now failing course
|
||||
Computes, saves, and returns a CourseGrade object for the given user and course.
|
||||
|
||||
send_grade_signals defines if signals should be sent. Use it to avoid recursion issues in
|
||||
cases when the signal listener trying to get grades but Persistent Grades are disabled.
|
||||
If True - sends:
|
||||
COURSE_GRADE_CHANGED signal to listeners and
|
||||
COURSE_GRADE_NOW_PASSED if learner has passed course or
|
||||
COURSE_GRADE_NOW_FAILED if learner is now failing course
|
||||
"""
|
||||
should_persist = should_persist_grades(course_data.course_key)
|
||||
if should_persist and force_update_subsections:
|
||||
@@ -193,26 +197,27 @@ class CourseGradeFactory:
|
||||
passed=course_grade.passed,
|
||||
)
|
||||
|
||||
COURSE_GRADE_CHANGED.send_robust(
|
||||
sender=None,
|
||||
user=user,
|
||||
course_grade=course_grade,
|
||||
course_key=course_data.course_key,
|
||||
deadline=course_data.course.end,
|
||||
)
|
||||
if course_grade.passed:
|
||||
COURSE_GRADE_NOW_PASSED.send(
|
||||
sender=CourseGradeFactory,
|
||||
if send_grade_signals:
|
||||
COURSE_GRADE_CHANGED.send_robust(
|
||||
sender=None,
|
||||
user=user,
|
||||
course_id=course_data.course_key,
|
||||
)
|
||||
else:
|
||||
COURSE_GRADE_NOW_FAILED.send(
|
||||
sender=CourseGradeFactory,
|
||||
user=user,
|
||||
course_id=course_data.course_key,
|
||||
grade=course_grade,
|
||||
course_grade=course_grade,
|
||||
course_key=course_data.course_key,
|
||||
deadline=course_data.course.end,
|
||||
)
|
||||
if course_grade.passed:
|
||||
COURSE_GRADE_NOW_PASSED.send(
|
||||
sender=CourseGradeFactory,
|
||||
user=user,
|
||||
course_id=course_data.course_key,
|
||||
)
|
||||
else:
|
||||
COURSE_GRADE_NOW_FAILED.send(
|
||||
sender=CourseGradeFactory,
|
||||
user=user,
|
||||
course_id=course_data.course_key,
|
||||
grade=course_grade,
|
||||
)
|
||||
|
||||
log.info(
|
||||
'Grades: Update, %s, User: %s, %s, persisted: %s',
|
||||
|
||||
Reference in New Issue
Block a user