From fe70769afcdf239577d59e330e32306d14107a48 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Mon, 8 Jun 2020 11:20:48 +0530 Subject: - Remove Copy Of in Module, Lesson and Quiz names when duplicating courses - Prevent student users from accessing Questions --- yaksh/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 7d4dd98..e86472c 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -296,7 +296,7 @@ class Lesson(models.Model): lesson_files = self.get_files() new_lesson = self new_lesson.id = None - new_lesson.name = "Copy of {0}".format(self.name) + new_lesson.name = self.name new_lesson.creator = user new_lesson.save() for _file in lesson_files: @@ -575,7 +575,7 @@ class Quiz(models.Model): question_papers = self.questionpaper_set.all() new_quiz = self new_quiz.id = None - new_quiz.description = "Copy of {0}".format(self.description) + new_quiz.description = self.description new_quiz.creator = user new_quiz.save() for qp in question_papers: @@ -932,7 +932,7 @@ class Course(models.Model): copy_course_name = "Copy Of {0}".format(self.name) new_course = self._create_duplicate_instance(user, copy_course_name) for module in learning_modules: - copy_module_name = "Copy of {0}".format(module.name) + copy_module_name = module.name new_module = module._create_module_copy(user, copy_module_name) new_course.learning_module.add(new_module) return new_course -- cgit From 49a494849a0498e309f6c97ec6ae6ab79961b87d Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Thu, 30 Jul 2020 22:14:44 +0530 Subject: Make changes based on feedback --- yaksh/models.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index e86472c..87a6877 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -296,7 +296,6 @@ class Lesson(models.Model): lesson_files = self.get_files() new_lesson = self new_lesson.id = None - new_lesson.name = self.name new_lesson.creator = user new_lesson.save() for _file in lesson_files: @@ -575,7 +574,6 @@ class Quiz(models.Model): question_papers = self.questionpaper_set.all() new_quiz = self new_quiz.id = None - new_quiz.description = self.description new_quiz.creator = user new_quiz.save() for qp in question_papers: @@ -821,12 +819,13 @@ class LearningModule(models.Model): percent = round((count / units.count()) * 100) return percent - def _create_module_copy(self, user, module_name): + def _create_module_copy(self, user, module_name=None): learning_units = self.learning_unit.order_by("order") new_module = self new_module.id = None - new_module.name = module_name new_module.creator = user + if module_name: + new_module.name = module_name new_module.save() for unit in learning_units: new_unit = unit._create_unit_copy(user) @@ -933,7 +932,7 @@ class Course(models.Model): new_course = self._create_duplicate_instance(user, copy_course_name) for module in learning_modules: copy_module_name = module.name - new_module = module._create_module_copy(user, copy_module_name) + new_module = module._create_module_copy(user) new_course.learning_module.add(new_module) return new_course -- cgit From 55d2800b61df661e7155f8b3cbd30ed047259f43 Mon Sep 17 00:00:00 2001 From: Jayram Date: Sun, 9 Aug 2020 22:16:56 +0530 Subject: [FIX] #546 - create_moderator command if User has no Profile --- yaksh/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 6542daa..0765ee8 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1279,7 +1279,7 @@ class Profile(models.Model): super(Profile, self).save(*args, **kwargs) def __str__(self): - return '%s' % (self.user.get_full_name()) + return '%s' % (self.user.get_full_name() or self.user.username) ############################################################################### -- cgit From 60503c9bd1ea49177f0adfc39ff129bfba86c9de Mon Sep 17 00:00:00 2001 From: prathamesh Date: Fri, 27 Nov 2020 04:18:27 +0530 Subject: Fix answer paper view. - Slight optimisation in retrieving and rendering the data - avoids the arrange type question's custom filter error - Marks obtained appears properly on all the interface(user view answerpaper, monitor and grade user) - if not attempted then shows the question and says "Did not attempt" --- yaksh/models.py | 55 +++++++++++++++++++++---------------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 50e9363..2978f43 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2321,14 +2321,20 @@ class AnswerPaper(models.Model): secs = dt.seconds + dt.days*24*3600 return secs + def _get_marks_for_question(self, question): + marks = 0.0 + answers = question.answer_set.filter(answerpaper=self) + if answers.exists(): + marks = [answer.marks for answer in answers] + max_marks = max(marks) + marks = max_marks + return marks + def _update_marks_obtained(self): """Updates the total marks earned by student for this paper.""" - marks = 0 + marks = 0.0 for question in self.questions.all(): - marks_list = [a.marks - for a in self.answers.filter(question=question)] - max_marks = max(marks_list) if marks_list else 0.0 - marks += max_marks + marks += self._get_marks_for_question(question) self.marks_obtained = marks def _update_percent(self): @@ -2376,38 +2382,19 @@ class AnswerPaper(models.Model): corresponding answers. """ q_a = {} - for answer in self.answers.all(): - question = answer.question - if question in q_a: - q_a[question].append({ - 'answer': answer, - 'error_list': [e for e in json.loads(answer.error)] - }) - else: - q_a[question] = [{ + for question in self.questions.all(): + answers = question.answer_set.filter(answerpaper=self) + if not answers.exists(): + q_a[question] = [None, 0.0] + continue + ans_errs = [] + for answer in answers: + ans_errs.append({ 'answer': answer, 'error_list': [e for e in json.loads(answer.error)] - }] - - q_a.update( - { q: [] for q in self.questions_unanswered.all() } - ) - - for question, answers in q_a.items(): - answers = q_a[question] - if answers: - q_a[question].append({ - 'marks': max([ - answer['answer'].marks - for answer in answers - if question == answer['answer'].question - ]), }) - else: - q_a[question].append({ - 'marks': 0.0, - }) - + q_a[question] = ans_errs + q_a[question].append(self._get_marks_for_question(question)) return q_a def get_latest_answer(self, question_id): -- cgit From aa0457d33ba098f2ef532aea10b888e7b9fd2ec9 Mon Sep 17 00:00:00 2001 From: adityacp Date: Fri, 11 Dec 2020 22:43:32 +0530 Subject: Refactor download quiz csv --- yaksh/models.py | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 2978f43..984a712 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -992,13 +992,13 @@ class Course(models.Model): return self.rejected.all() def is_enrolled(self, user): - return user in self.students.all() + return self.students.filter(id=user.id).exists() def is_creator(self, user): return self.creator == user def is_teacher(self, user): - return True if user in self.teachers.all() else False + return self.teachers.filter(id=user.id).exists() def is_self_enroll(self): return True if self.enrollment == enrollment_methods[1][0] else False @@ -1062,7 +1062,7 @@ class Course(models.Model): return success def get_only_students(self): - teachers = list(self.teachers.all().values_list("id", flat=True)) + teachers = list(self.teachers.values_list("id", flat=True)) teachers.append(self.creator.id) students = self.students.exclude(id__in=teachers) return students @@ -1181,7 +1181,7 @@ class Course(models.Model): return percentage def is_student(self, user): - return user in self.students.all() + return self.students.filter(id=user.id).exists() def create_zip(self, path, static_files): zip_file_name = string_io() @@ -2212,15 +2212,27 @@ class AnswerPaper(models.Model): 'attempt_number', "course" ) - def get_per_question_score(self, question_id): - questions = self.get_questions().values_list('id', flat=True) - if question_id not in questions: - return 'NA' - answer = self.get_latest_answer(question_id) - if answer: - return answer.marks - else: - return 0 + def get_per_question_score(self, question_ids): + que_ids = list(zip(*question_ids))[1] + answers = self.answers.filter( + question_id__in=que_ids).values("question_id", "marks") + que_data = {} + df = pd.DataFrame(answers) + ans_data = None + if not df.empty: + ans_data = df.groupby("question_id").tail(1) + for que_summary, que_id in question_ids: + if ans_data is not None: + ans = ans_data['question_id'].to_list() + marks = ans_data['marks'].to_list() + if que_id in ans: + idx = ans.index(que_id) + que_data[que_summary] = marks[idx] + else: + que_data[que_summary] = 0 + else: + que_data[que_summary] = 0 + return que_data def current_question(self): """Returns the current active question to display.""" -- cgit From 93860c0fb3c61d64878ff73c3c28ec3fd4e1ad7a Mon Sep 17 00:00:00 2001 From: adityacp Date: Mon, 14 Dec 2020 21:08:50 +0530 Subject: Refactor and optimize code for download course csv --- yaksh/models.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 984a712..9153367 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2134,11 +2134,38 @@ class AnswerPaperManager(models.Manager): best_attempt = 0.0 papers = self.filter(question_paper__quiz_id=quiz.id, course_id=course_id, - user=user_id).values("marks_obtained") - if papers: - best_attempt = max([marks["marks_obtained"] for marks in papers]) + user=user_id).order_by("-marks_obtained").values( + "marks_obtained") + if papers.exists(): + best_attempt = papers[0]["marks_obtained"] return best_attempt + def get_user_scores(self, question_papers, user, course_id): + qp_ids = list(zip(*question_papers))[0] + papers = self.filter( + course_id=course_id, user_id=user.get("id"), + question_paper__id__in=qp_ids + ).values("question_paper_id", "marks_obtained") + df = pd.DataFrame(papers) + user_marks = 0 + ap_data = None + if not df.empty: + ap_data = df.groupby("question_paper_id").tail(1) + for qp_id, quiz, quiz_marks in question_papers: + if ap_data is not None: + qp = ap_data['question_paper_id'].to_list() + marks = ap_data['marks_obtained'].to_list() + if qp_id in qp: + idx = qp.index(qp_id) + user_marks += marks[idx] + user[f"{quiz}-{quiz_marks}-Marks"] = marks[idx] + else: + user[f"{quiz}-{quiz_marks}-Marks"] = 0 + else: + user[f"{quiz}-{quiz_marks}-Marks"] = 0 + user.pop("id") + user["total_marks"] = user_marks + ############################################################################### class AnswerPaper(models.Model): -- cgit From a29473b7ac933b31368ca163c758e8eadb4c411e Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 22 Dec 2020 12:48:23 +0530 Subject: Fix UI in lesson statistics --- yaksh/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 2978f43..a29e910 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2830,7 +2830,7 @@ class TOCManager(models.Manager): if answers.exists(): answers = answers.values( "student__first_name", "student__last_name", "student__email", - "student_id", "toc_id" + "student_id", "student__profile__roll_number", "toc_id" ) df = pd.DataFrame(answers) answers = df.drop_duplicates().to_dict(orient='records') -- cgit From bed14cfa684fc3a97a5bfbd6441dc1ddf2e77346 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Fri, 1 May 2020 16:32:30 +0530 Subject: Delete and recreate question papers when using god mode or user mode --- yaksh/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index a29e910..99cbf70 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1754,7 +1754,8 @@ class QuestionPaperManager(models.Manager): def create_trial_paper_to_test_quiz(self, trial_quiz, original_quiz_id): """Creates a trial question paper to test quiz.""" - trial_quiz.questionpaper_set.all().delete() + if self.filter(quiz=trial_quiz).exists(): + self.get(quiz=trial_quiz).delete() trial_questionpaper, trial_questions = \ self._create_trial_from_questionpaper(original_quiz_id) trial_questionpaper.quiz = trial_quiz -- cgit From e50673216aaea50d9e14cc10d8e7fc03b2a8ea42 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Wed, 23 Sep 2020 22:49:27 +0530 Subject: Add feature to count number of times MCQ option has been selected --- yaksh/models.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index a29e910..abff541 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1993,6 +1993,32 @@ class AnswerPaperManager(models.Manager): questions.append(question.id) return Counter(questions) + def get_per_answer_stats(self, questionpaper_id, attempt_number, + course_id, status='completed'): + papers = self.filter(question_paper_id=questionpaper_id, + course_id=course_id, + attempt_number=attempt_number, status=status) + questions = Question.objects.filter( + questions__id__in=papers, + ).distinct() + + stats = {} + for question in questions: + answers = Answer.objects.filter( + answerpaper__id__in=papers, question=question.id + ).values('answer', 'question__id', 'answerpaper__id') + question_ans_count = {} + answerpaper_count = [] + for ans in answers: + if ans.get('answerpaper__id'): + if ans.get('answer') not in question_ans_count: + question_ans_count[ans.get('answer')] = 1 + else: + question_ans_count[ans.get('answer')] += 1 + answerpaper_count.append(ans.get('answerpaper__id')) + stats[question] = question_ans_count + return stats + def get_all_questions_answered(self, questionpaper_id, attempt_number, course_id, status='completed'): ''' Return a dict of answered question id as key and count as value''' @@ -2046,16 +2072,27 @@ class AnswerPaperManager(models.Manager): course_id) questions = self.get_all_questions(questionpaper_id, attempt_number, course_id) + per_answer_stats = self.get_per_answer_stats( + questionpaper_id, attempt_number, course_id + ) all_questions = Question.objects.filter( id__in=set(questions), active=True ).order_by('type') for question in all_questions: if question.id in questions_answered: - question_stats[question] = [questions_answered[question.id], - questions[question.id]] + question_stats[question] = { + 'answered': [questions_answered[question.id], + questions[question.id]], + 'per_answer': per_answer_stats[question], + } + else: - question_stats[question] = [0, questions[question.id]] + question_stats[question] = { + 'answered': [0, questions[question.id]], + 'per_answer': per_answer_stats[question], + } + return question_stats def _get_answerpapers_for_quiz(self, questionpaper_id, course_id, -- cgit From 7cf18e744c9260ebd33f6233d0211a3c0aa3a782 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Fri, 27 Nov 2020 15:04:30 +0530 Subject: Add a feature to upload and download --- yaksh/models.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index a29e910..bdac927 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1381,7 +1381,7 @@ class Question(models.Model): # Solution for the question. solution = models.TextField(blank=True) - content = GenericRelation("TableOfContents") + content = GenericRelation("TableOfContents", related_query_name='questions') tc_code_types = { "python": [ @@ -2823,6 +2823,17 @@ class TOCManager(models.Manager): "student_id", flat=True).distinct().count() return data + def get_all_tocs_as_yaml(self, course_id, lesson_id, file_path): + all_tocs = TableOfContents.objects.filter( + course_id=course_id, lesson_id=lesson_id, + ) + if not all_tocs.exists(): + return None + for toc in all_tocs: + toc.get_toc_as_yaml(file_path) + return file_path + + def get_question_stats(self, toc_id): answers = LessonQuizAnswer.objects.get_queryset().filter( toc_id=toc_id).order_by('id') @@ -2929,7 +2940,7 @@ class TOCManager(models.Manager): else: que = Question.objects.create(**content) for test_case in test_cases: - test_case_type = test_case.pop('test_case_type') + test_case_type = test_case.pop('type') model_class = get_model_class(test_case_type) model_class.objects.get_or_create( question=que, **test_case, type=test_case_type @@ -2971,6 +2982,39 @@ class TableOfContents(models.Model): content_name = self.content_object.summary return content_name + def get_toc_as_yaml(self, file_path): + data = {'content_type': self.content, 'time': self.time} + if self.topics.exists(): + content = self.topics.first() + data.update( + { + 'name': content.name, + 'description': content.description, + } + ) + elif self.questions.exists(): + content = self.questions.first() + tc_data = [] + for tc in content.get_test_cases(): + _tc_as_dict = model_to_dict( + tc, exclude=['id', 'testcase_ptr', 'question'], + ) + tc_data.append(_tc_as_dict) + data.update( + { + 'summary': content.summary, + 'type': content.type, + 'language': content.language, + 'description': content.description, + 'points': content.points, + 'testcase': tc_data, + } + ) + yaml_block = dict_to_yaml(data) + with open(file_path, "a") as yaml_file: + yaml_file.write(yaml_block) + return yaml_file + def __str__(self): return f"TOC for {self.lesson.name} with {self.get_content_display()}" @@ -2978,7 +3022,7 @@ class TableOfContents(models.Model): class Topic(models.Model): name = models.CharField(max_length=255) description = models.TextField(null=True, blank=True) - content = GenericRelation(TableOfContents) + content = GenericRelation(TableOfContents, related_query_name='topics') def __str__(self): return f"{self.name}" -- cgit From 3966ae20fc68041721f97c45ff92102ed5729aee Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Sat, 16 Jan 2021 23:42:30 +0530 Subject: Fix failing test case --- yaksh/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index bdac927..00bca5b 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2940,7 +2940,7 @@ class TOCManager(models.Manager): else: que = Question.objects.create(**content) for test_case in test_cases: - test_case_type = test_case.pop('type') + test_case_type = test_case.pop('test_case_type') model_class = get_model_class(test_case_type) model_class.objects.get_or_create( question=que, **test_case, type=test_case_type -- cgit From c474c68a2621e8c470ce2751103128fa793be62e Mon Sep 17 00:00:00 2001 From: adityacp Date: Mon, 25 Jan 2021 10:54:25 +0530 Subject: Refactor code for download csv for course progress --- yaksh/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index b0247ac..7609859 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1159,7 +1159,7 @@ class Course(models.Model): return grade def get_current_unit(self, user): - course_status = CourseStatus.objects.filter(course=self, user=user) + course_status = CourseStatus.objects.filter(course=self, user_id=user) if course_status.exists(): return course_status.first().current_unit -- cgit From 1e5c8af8748602d90a52f51d45799274155f8cd9 Mon Sep 17 00:00:00 2001 From: adityacp Date: Mon, 25 Jan 2021 13:12:56 +0530 Subject: Fix views and models tests --- yaksh/models.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 7609859..3e3e2d1 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2178,6 +2178,8 @@ class AnswerPaperManager(models.Manager): return best_attempt def get_user_scores(self, question_papers, user, course_id): + if not question_papers: + return None qp_ids = list(zip(*question_papers))[0] papers = self.filter( course_id=course_id, user_id=user.get("id"), @@ -2277,6 +2279,8 @@ class AnswerPaper(models.Model): ) def get_per_question_score(self, question_ids): + if not question_ids: + return None que_ids = list(zip(*question_ids))[1] answers = self.answers.filter( question_id__in=que_ids).values("question_id", "marks") -- cgit From 7f28b418b616823f542faea8311e881faf6286c2 Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 26 Jan 2021 14:38:46 +0530 Subject: Refactor question statistics for a quiz --- yaksh/models.py | 65 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 28 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 3e3e2d1..bbb6900 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2063,36 +2063,45 @@ class AnswerPaperManager(models.Manager): def get_question_statistics(self, questionpaper_id, attempt_number, course_id, status='completed'): ''' Return dict with question object as key and list as value - The list contains two value, first the number of times a question - was answered correctly, and second the number of times a question - appeared in a quiz''' + The list contains four values, first total attempts, second correct + attempts, third correct percentage, fourth per test case answers + a question + ''' question_stats = {} - questions_answered = self.get_all_questions_answered(questionpaper_id, - attempt_number, - course_id) - questions = self.get_all_questions(questionpaper_id, attempt_number, - course_id) - per_answer_stats = self.get_per_answer_stats( - questionpaper_id, attempt_number, course_id + qp = QuestionPaper.objects.get(id=questionpaper_id) + all_questions = qp.get_question_bank() + que_ids = [que.id for que in all_questions] + papers = self.filter( + question_paper_id=questionpaper_id, course_id=course_id, + attempt_number=attempt_number + ).values_list("id", flat=True) + answers = Answer.objects.filter( + answerpaper__id__in=papers, question_id__in=que_ids + ).order_by("id").values( + "answerpaper__id", "question_id", "correct", "answer" ) - all_questions = Question.objects.filter( - id__in=set(questions), - active=True - ).order_by('type') - for question in all_questions: - if question.id in questions_answered: - question_stats[question] = { - 'answered': [questions_answered[question.id], - questions[question.id]], - 'per_answer': per_answer_stats[question], - } - - else: - question_stats[question] = { - 'answered': [0, questions[question.id]], - 'per_answer': per_answer_stats[question], - } - + def _get_per_tc_data(answers, q_type): + tc = [] + for answer in answers["answer"]: + ans = literal_eval(answer) if answer else None + tc.extend(ans) if q_type == "mcc" else tc.append(str(ans)) + return dict(Counter(tc)) + df = pd.DataFrame(answers) + if not df.empty: + for question in all_questions: + que = df[df["question_id"]==question.id].groupby( + "answerpaper__id").tail(1) + if not que.empty: + total_attempts = que.shape[0] + correct_attempts = que[que["correct"]==True].shape[0] + per_tc_ans = {} + if question.type in ["mcq", "mcc"]: + per_tc_ans = _get_per_tc_data(que, question.type) + question_stats[question] = ( + total_attempts, correct_attempts, + round((correct_attempts/total_attempts)*100), + per_tc_ans + ) return question_stats def _get_answerpapers_for_quiz(self, questionpaper_id, course_id, -- cgit From fa8020b9f39b4e75a0a5d8b26653cc61cb9ae981 Mon Sep 17 00:00:00 2001 From: adityacp Date: Wed, 27 Jan 2021 16:36:51 +0530 Subject: Refactor monitor for a quiz --- yaksh/models.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index bbb6900..662a8b4 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1953,6 +1953,12 @@ class QuestionPaper(models.Model): list(self.random_questions.all()) return len(questions) > 0 + def get_questions_count(self): + que_count = self.fixed_questions.count() + for r_set in self.random_questions.all(): + que_count += r_set.num_questions + return que_count + def __str__(self): return "Question Paper for " + self.quiz.description @@ -2214,6 +2220,17 @@ class AnswerPaperManager(models.Manager): user.pop("id") user["total_marks"] = user_marks + def get_questions_attempted(self, answerpaper_ids): + answers = Answer.objects.filter( + answerpaper__id__in=answerpaper_ids + ).values("question_id", "answerpaper__id") + df = pd.DataFrame(answers) + answerpapers = df.groupby("answerpaper__id") + question_attempted = {} + for ap in answerpapers: + question_attempted[ap[0]] = len(ap[1]["question_id"].unique()) + return question_attempted + ############################################################################### class AnswerPaper(models.Model): @@ -2472,7 +2489,7 @@ class AnswerPaper(models.Model): """ q_a = {} for question in self.questions.all(): - answers = question.answer_set.filter(answerpaper=self) + answers = question.answer_set.filter(answerpaper=self).distinct() if not answers.exists(): q_a[question] = [None, 0.0] continue -- cgit From fca319fefcd2a0e476415968b18873b0c791a5fe Mon Sep 17 00:00:00 2001 From: adityacp Date: Mon, 1 Feb 2021 17:38:00 +0530 Subject: Change templates and models - Remove unwanted model manager methods - Minor UI refactor for course and question interface --- yaksh/models.py | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 662a8b4..0f62948 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1985,58 +1985,6 @@ class QuestionSet(models.Model): ############################################################################### class AnswerPaperManager(models.Manager): - def get_all_questions(self, questionpaper_id, attempt_number, course_id, - status='completed'): - ''' Return a dict of question id as key and count as value''' - papers = self.filter(question_paper_id=questionpaper_id, - course_id=course_id, - attempt_number=attempt_number, status=status) - all_questions = list() - questions = list() - for paper in papers: - all_questions += paper.get_questions() - for question in all_questions: - questions.append(question.id) - return Counter(questions) - - def get_per_answer_stats(self, questionpaper_id, attempt_number, - course_id, status='completed'): - papers = self.filter(question_paper_id=questionpaper_id, - course_id=course_id, - attempt_number=attempt_number, status=status) - questions = Question.objects.filter( - questions__id__in=papers, - ).distinct() - - stats = {} - for question in questions: - answers = Answer.objects.filter( - answerpaper__id__in=papers, question=question.id - ).values('answer', 'question__id', 'answerpaper__id') - question_ans_count = {} - answerpaper_count = [] - for ans in answers: - if ans.get('answerpaper__id'): - if ans.get('answer') not in question_ans_count: - question_ans_count[ans.get('answer')] = 1 - else: - question_ans_count[ans.get('answer')] += 1 - answerpaper_count.append(ans.get('answerpaper__id')) - stats[question] = question_ans_count - return stats - - def get_all_questions_answered(self, questionpaper_id, attempt_number, - course_id, status='completed'): - ''' Return a dict of answered question id as key and count as value''' - papers = self.filter(question_paper_id=questionpaper_id, - course_id=course_id, - attempt_number=attempt_number, status=status) - questions_answered = list() - for paper in papers: - for question in filter(None, paper.get_questions_answered()): - if paper.is_answer_correct(question): - questions_answered.append(question.id) - return Counter(questions_answered) def get_attempt_numbers(self, questionpaper_id, course_id, status='completed'): -- cgit From 7cf71fe471553c7b0f92d96f3b2da48d06eaa43d Mon Sep 17 00:00:00 2001 From: adityacp Date: Mon, 8 Feb 2021 11:28:18 +0530 Subject: Release changes --- yaksh/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 0f62948..b4d0f76 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1067,7 +1067,7 @@ class Course(models.Model): return students def get_learning_modules(self): - return self.learning_module.order_by("order") + return self.learning_module.filter(is_trial=False).order_by("order") def get_learning_module(self, quiz): modules = self.get_learning_modules() -- cgit From 8c1c1f6c8b1de16fba5f93e58a0cd3cb751e02d7 Mon Sep 17 00:00:00 2001 From: adityacp Date: Wed, 10 Feb 2021 19:02:29 +0530 Subject: Change in templates, views - Revamp UI in course page - Fix a bug where a trial module is created without setting is_trial in models - Fix a bug in question statistics where only completed answerpaper data is needed --- yaksh/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index b4d0f76..5934ae2 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2027,7 +2027,7 @@ class AnswerPaperManager(models.Manager): que_ids = [que.id for que in all_questions] papers = self.filter( question_paper_id=questionpaper_id, course_id=course_id, - attempt_number=attempt_number + attempt_number=attempt_number, status=status ).values_list("id", flat=True) answers = Answer.objects.filter( answerpaper__id__in=papers, question_id__in=que_ids -- cgit From ed50666eceb10b7c8cfa1352ffde2c1025f3aa9a Mon Sep 17 00:00:00 2001 From: adityacp Date: Thu, 11 Feb 2021 11:04:59 +0530 Subject: Fix issue in pandas dataframe where key is not available --- yaksh/models.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 5934ae2..16800fe 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2173,11 +2173,12 @@ class AnswerPaperManager(models.Manager): answerpaper__id__in=answerpaper_ids ).values("question_id", "answerpaper__id") df = pd.DataFrame(answers) - answerpapers = df.groupby("answerpaper__id") - question_attempted = {} - for ap in answerpapers: - question_attempted[ap[0]] = len(ap[1]["question_id"].unique()) - return question_attempted + if not df.empty and "answerpaper__id" in df.columns: + answerpapers = df.groupby("answerpaper__id") + question_attempted = {} + for ap in answerpapers: + question_attempted[ap[0]] = len(ap[1]["question_id"].unique()) + return question_attempted ############################################################################### -- cgit From 51039188a191a46afd4e3c499e2a035e3bc1ceba Mon Sep 17 00:00:00 2001 From: adityacp Date: Thu, 11 Feb 2021 14:15:41 +0530 Subject: Fix monitor to get all the attempts properly --- yaksh/models.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 16800fe..11ddf8a 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2037,8 +2037,11 @@ class AnswerPaperManager(models.Manager): def _get_per_tc_data(answers, q_type): tc = [] for answer in answers["answer"]: - ans = literal_eval(answer) if answer else None - tc.extend(ans) if q_type == "mcc" else tc.append(str(ans)) + try: + ans = literal_eval(answer) if answer else None + tc.extend(ans) if q_type == "mcc" else tc.append(str(ans)) + except Exception: + pass return dict(Counter(tc)) df = pd.DataFrame(answers) if not df.empty: -- cgit From 1a2d31e1c59427c28211030ea09cd4964b4bd8d8 Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 16 Feb 2021 15:21:24 +0530 Subject: Change test data files, views, models, template - Fix upload marks for a quiz column missing error - Add upload marks task to celery - Minor fixes to avoid errors in regrade and custom_filters --- yaksh/models.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 11ddf8a..77b3684 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2267,7 +2267,7 @@ class AnswerPaper(models.Model): ans_data = None if not df.empty: ans_data = df.groupby("question_id").tail(1) - for que_summary, que_id in question_ids: + for que_summary, que_id, que_comments in question_ids: if ans_data is not None: ans = ans_data['question_id'].to_list() marks = ans_data['marks'].to_list() @@ -2278,6 +2278,7 @@ class AnswerPaper(models.Model): que_data[que_summary] = 0 else: que_data[que_summary] = 0 + que_data[que_comments] = "NA" return que_data def current_question(self): @@ -2576,25 +2577,17 @@ class AnswerPaper(models.Model): self.user, self.question_paper.quiz.description, question_id ) - return False, msg + 'Question not in the answer paper.' + return False, f'{msg} Question not in the answer paper.' user_answer = self.answers.filter(question=question).last() - if not user_answer: - return False, msg + 'Did not answer.' + if not user_answer or not user_answer.answer: + return False, f'{msg} Did not answer.' if question.type in ['mcc', 'arrange']: try: answer = literal_eval(user_answer.answer) if type(answer) is not list: - return (False, - msg + '{0} answer not a list.'.format( - question.type - ) - ) + return (False, f'{msg} {question.type} answer not a list.') except Exception: - return (False, - msg + '{0} answer submission error'.format( - question.type - ) - ) + return (False, f'{msg} {question.type} answer submission error') else: answer = user_answer.answer json_data = question.consolidate_answer_data(answer) \ -- cgit From 9a2717b662c7dd3fca54e8b8f2e526454ad72d83 Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Fri, 19 Feb 2021 15:05:42 +0530 Subject: Fix upload assignment issue for multiple attempts --- yaksh/models.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 11ddf8a..6a745d1 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -122,7 +122,7 @@ MOD_GROUP_NAME = 'moderator' def get_assignment_dir(instance, filename): folder_name = instance.course.name.replace(" ", "_") - sub_folder_name = instance.question_paper.quiz.description.replace( + sub_folder_name = instance.answer_paper.question_paper.quiz.description.replace( " ", "_") return os.sep.join((folder_name, sub_folder_name, instance.user.username, str(instance.assignmentQuestion.id), @@ -2661,9 +2661,10 @@ class AssignmentUploadManager(models.Manager): class AssignmentUpload(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) assignmentQuestion = models.ForeignKey(Question, on_delete=models.CASCADE) - assignmentFile = models.FileField(upload_to=get_assignment_dir, max_length=255) - question_paper = models.ForeignKey(QuestionPaper, blank=True, null=True, - on_delete=models.CASCADE) + assignmentFile = models.FileField(upload_to=get_assignment_dir, + max_length=255) + answer_paper = models.ForeignKey(AnswerPaper, blank=True, null=True, + on_delete=models.CASCADE) course = models.ForeignKey(Course, null=True, blank=True, on_delete=models.CASCADE) objects = AssignmentUploadManager() -- cgit From 3e23a631e9c8e25fd13c7f1f8b0fed54d0c34b8f Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Fri, 26 Feb 2021 08:37:27 +0530 Subject: Fix assignment download on grade user interface --- yaksh/models.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 6a745d1..b80f98c 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -121,10 +121,10 @@ MOD_GROUP_NAME = 'moderator' def get_assignment_dir(instance, filename): - folder_name = instance.course.name.replace(" ", "_") - sub_folder_name = instance.answer_paper.question_paper.quiz.description.replace( - " ", "_") - return os.sep.join((folder_name, sub_folder_name, instance.user.username, + folder = str(instance.answer_paper.course.id) + sub_folder = str(instance.answer_paper.question_paper.quiz.id) + user = instance.answer_paper.user.username + return os.sep.join((folder, sub_folder, user, str(instance.assignmentQuestion.id), filename )) @@ -1439,7 +1439,7 @@ class Question(models.Model): for file in files] if self.type == "upload": assignment_files = AssignmentUpload.objects.filter( - assignmentQuestion=self, user=user + assignmentQuestion=self ) if assignment_files: metadata['assign_files'] = [(file.assignmentFile.path, False) @@ -2642,16 +2642,16 @@ class AssignmentUploadManager(models.Manager): def get_assignments(self, qp, que_id=None, user_id=None, course_id=None): if que_id and user_id: assignment_files = AssignmentUpload.objects.filter( - assignmentQuestion_id=que_id, user_id=user_id, - question_paper=qp, course_id=course_id + assignmentQuestion_id=que_id, answer_paper__user_id=user_id, + answer_paper__question_paper=qp, answer_paper__course_id=course_id ) file_name = User.objects.get(id=user_id).get_full_name() else: assignment_files = AssignmentUpload.objects.filter( - question_paper=qp, course_id=course_id + answer_paper__question_paper=qp, answer_paper__course_id=course_id ) file_name = "{0}_Assignment_files".format( - assignment_files[0].course.name + assignment_files[0].answer_paper.course.name ) return assignment_files, file_name @@ -2659,16 +2659,18 @@ class AssignmentUploadManager(models.Manager): ############################################################################## class AssignmentUpload(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE) assignmentQuestion = models.ForeignKey(Question, on_delete=models.CASCADE) assignmentFile = models.FileField(upload_to=get_assignment_dir, max_length=255) answer_paper = models.ForeignKey(AnswerPaper, blank=True, null=True, on_delete=models.CASCADE) - course = models.ForeignKey(Course, null=True, blank=True, - on_delete=models.CASCADE) + upload_date = models.DateTimeField(auto_now=True) + objects = AssignmentUploadManager() + def __str__(self): + return f'Assignment File of the user {self.answer_paper.user}' + ############################################################################## class TestCase(models.Model): -- cgit From 2d46e6799672cc133829ab72a88c645e54087d98 Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Fri, 26 Feb 2021 12:54:37 +0530 Subject: Resolve comments --- yaksh/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index b80f98c..ca0f2d8 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -121,8 +121,8 @@ MOD_GROUP_NAME = 'moderator' def get_assignment_dir(instance, filename): - folder = str(instance.answer_paper.course.id) - sub_folder = str(instance.answer_paper.question_paper.quiz.id) + folder = str(instance.answer_paper.course_id) + sub_folder = str(instance.answer_paper.question_paper.quiz_id) user = instance.answer_paper.user.username return os.sep.join((folder, sub_folder, user, str(instance.assignmentQuestion.id), -- cgit From 085b1fae43a16cff87e1ab0cf3730e84d4943442 Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Wed, 3 Mar 2021 23:55:24 +0530 Subject: Fix failing test --- yaksh/models.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index ca0f2d8..30c69c3 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -121,15 +121,16 @@ MOD_GROUP_NAME = 'moderator' def get_assignment_dir(instance, filename): - folder = str(instance.answer_paper.course_id) - sub_folder = str(instance.answer_paper.question_paper.quiz_id) + course = instance.answer_paper.course + quiz = instance.answer_paper.question_paper.quiz + folder = f'{course.name.replace(" ", "_")}_{course.id}' + sub_folder = f'{quiz.description.replace(" ","_")}_{quiz.id}' user = instance.answer_paper.user.username return os.sep.join((folder, sub_folder, user, str(instance.assignmentQuestion.id), filename )) - def get_model_class(model): ctype = ContentType.objects.get(app_label="yaksh", model=model) model_class = ctype.model_class() -- cgit From ccc578beff8363ea19826d6c621dafabe210531f Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Thu, 4 Mar 2021 16:49:55 +0530 Subject: Minor Change in get_assignment_dir --- yaksh/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 30c69c3..e88a9e4 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -123,8 +123,8 @@ MOD_GROUP_NAME = 'moderator' def get_assignment_dir(instance, filename): course = instance.answer_paper.course quiz = instance.answer_paper.question_paper.quiz - folder = f'{course.name.replace(" ", "_")}_{course.id}' - sub_folder = f'{quiz.description.replace(" ","_")}_{quiz.id}' + folder = f'Course_{course.id}' + sub_folder = f'Quiz_{quiz.id}' user = instance.answer_paper.user.username return os.sep.join((folder, sub_folder, user, str(instance.assignmentQuestion.id), -- cgit From b457c973b491d373ed9c5087b61bf29ce128d766 Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Mon, 15 Mar 2021 13:40:12 +0530 Subject: Replacing .id with _id in get_assignment_dir() - .id fetches entire model which is unnecessary. _id only fetches the primary key. --- yaksh/models.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index e88a9e4..4661ea7 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -121,13 +121,13 @@ MOD_GROUP_NAME = 'moderator' def get_assignment_dir(instance, filename): - course = instance.answer_paper.course - quiz = instance.answer_paper.question_paper.quiz - folder = f'Course_{course.id}' - sub_folder = f'Quiz_{quiz.id}' + course_id = instance.answer_paper.course_id + quiz_id = instance.answer_paper.question_paper.quiz_id + folder = f'Course_{course_id}' + sub_folder = f'Quiz_{quiz_id}' user = instance.answer_paper.user.username return os.sep.join((folder, sub_folder, user, - str(instance.assignmentQuestion.id), + str(instance.assignmentQuestion_id), filename )) -- cgit From 1793f445ec0cbc67df4b4cd3151859e01ed4b2a0 Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Mon, 15 Mar 2021 14:59:55 +0530 Subject: PEP8 fix --- yaksh/models.py | 54 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'yaksh/models.py') diff --git a/yaksh/models.py b/yaksh/models.py index 4661ea7..610e984 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -131,6 +131,7 @@ def get_assignment_dir(instance, filename): filename )) + def get_model_class(model): ctype = ContentType.objects.get(app_label="yaksh", model=model) model_class = ctype.model_class() @@ -1381,7 +1382,9 @@ class Question(models.Model): # Solution for the question. solution = models.TextField(blank=True) - content = GenericRelation("TableOfContents", related_query_name='questions') + content = GenericRelation( + "TableOfContents", related_query_name='questions' + ) tc_code_types = { "python": [ @@ -1838,7 +1841,8 @@ class QuestionPaper(models.Model): all_questions = questions return all_questions - def make_answerpaper(self, user, ip, attempt_num, course_id, special=False): + def make_answerpaper(self, + user, ip, attempt_num, course_id, special=False): """Creates an answer paper for the user to attempt the quiz""" try: ans_paper = AnswerPaper.objects.get(user=user, @@ -2035,6 +2039,7 @@ class AnswerPaperManager(models.Manager): ).order_by("id").values( "answerpaper__id", "question_id", "correct", "answer" ) + def _get_per_tc_data(answers, q_type): tc = [] for answer in answers["answer"]: @@ -2047,11 +2052,11 @@ class AnswerPaperManager(models.Manager): df = pd.DataFrame(answers) if not df.empty: for question in all_questions: - que = df[df["question_id"]==question.id].groupby( + que = df[df["question_id"] == question.id].groupby( "answerpaper__id").tail(1) if not que.empty: total_attempts = que.shape[0] - correct_attempts = que[que["correct"]==True].shape[0] + correct_attempts = que[que["correct"] == True].shape[0] per_tc_ans = {} if question.type in ["mcq", "mcc"]: per_tc_ans = _get_per_tc_data(que, question.type) @@ -2643,13 +2648,16 @@ class AssignmentUploadManager(models.Manager): def get_assignments(self, qp, que_id=None, user_id=None, course_id=None): if que_id and user_id: assignment_files = AssignmentUpload.objects.filter( - assignmentQuestion_id=que_id, answer_paper__user_id=user_id, - answer_paper__question_paper=qp, answer_paper__course_id=course_id + assignmentQuestion_id=que_id, + answer_paper__user_id=user_id, + answer_paper__question_paper=qp, + answer_paper__course_id=course_id ) file_name = User.objects.get(id=user_id).get_full_name() else: assignment_files = AssignmentUpload.objects.filter( - answer_paper__question_paper=qp, answer_paper__course_id=course_id + answer_paper__question_paper=qp, + answer_paper__course_id=course_id ) file_name = "{0}_Assignment_files".format( assignment_files[0].answer_paper.course.name @@ -2895,7 +2903,6 @@ class TOCManager(models.Manager): toc.get_toc_as_yaml(file_path) return file_path - def get_question_stats(self, toc_id): answers = LessonQuizAnswer.objects.get_queryset().filter( toc_id=toc_id).order_by('id') @@ -2929,7 +2936,7 @@ class TOCManager(models.Manager): if j not in mydata: mydata[j] = 1 else: - mydata[j] +=1 + mydata[j] += 1 data = mydata.copy() if is_percent: for key, value in data.items(): @@ -2975,17 +2982,20 @@ class TOCManager(models.Manager): if not is_valid_time_format(time): messages.append( (False, - f"Invalid time format in {name}. " + f"Invalid time format in {name}. " "Format should be 00:00:00") - ) + ) else: if content_type == 1: topic = Topic.objects.create(**content) toc.append(TableOfContents( - course_id=course_id, lesson_id=lesson_id, time=time, - content_object=topic, content=content_type + course_id=course_id, + lesson_id=lesson_id, time=time, + content_object=topic, content=content_type )) - messages.append((True, f"{topic.name} added successfully")) + messages.append( + (True, f"{topic.name} added successfully") + ) else: content['user'] = user test_cases = content.pop("testcase") @@ -3002,10 +3012,13 @@ class TOCManager(models.Manager): else: que = Question.objects.create(**content) for test_case in test_cases: - test_case_type = test_case.pop('test_case_type') + test_case_type = test_case.pop( + 'test_case_type' + ) model_class = get_model_class(test_case_type) model_class.objects.get_or_create( - question=que, **test_case, type=test_case_type + question=que, + **test_case, type=test_case_type ) toc.append(TableOfContents( course_id=course_id, lesson_id=lesson_id, @@ -3021,7 +3034,12 @@ class TOCManager(models.Manager): class TableOfContents(models.Model): - toc_types = ((1, "Topic"), (2, "Graded Quiz"), (3, "Exercise"), (4, "Poll")) + toc_types = ( + (1, "Topic"), + (2, "Graded Quiz"), + (3, "Exercise"), + (4, "Poll") + ) course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='course') lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, @@ -3039,7 +3057,7 @@ class TableOfContents(models.Model): def get_toc_text(self): if self.content == 1: - content_name = self.content_object.name + content_name = self.content_object.name else: content_name = self.content_object.summary return content_name -- cgit