|
@@ -50,7 +50,7 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
if serializer.is_valid(raise_exception=True):
|
|
|
instance = serializer.save()
|
|
|
result = {
|
|
|
- 'practise': instance.id, # 练习题 id
|
|
|
+ 'practise': instance.id, # 练习题 id
|
|
|
}
|
|
|
return response_ok(result)
|
|
|
except ValidationError as e:
|
|
@@ -61,8 +61,8 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
def get_next_practise(self, request, pk):
|
|
|
now_practise = request.data.get('now_practise') # 当前提交的练习题。第一题或继续答题时,该参数为空
|
|
|
answers = json.loads(request.data.get('answers')) # 答案, 第一题或继续答题时,该参数为空
|
|
|
- next_number = int(request.data.get('next_number')) or 0 # 下一题序号, 第一题提交为空
|
|
|
- next_practise = request.data.get('next_practise') # 下一题id,首次加载第一题,传空
|
|
|
+ next_number = request.data.get('next_number') or 0 # 下一题序号, 第一题提交为空,不在使用
|
|
|
+ next_practise = request.data.get('next_practise') # 下一题id,首次加载第一题,传空
|
|
|
try:
|
|
|
with transaction.atomic():
|
|
|
instance = self.get_object()
|
|
@@ -72,19 +72,19 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
if not now_question:
|
|
|
raise CustomError('提交的习题有误,请刷新重试!')
|
|
|
if len(answers) > 0:
|
|
|
- answer_log, create = PractiseAnswerLog.objects.get_or_create(main=instance, question=now_question,)
|
|
|
+ answer_log, create = PractiseAnswerLog.objects.get_or_create(main=instance,
|
|
|
+ question=now_question, )
|
|
|
if now_question.type == ExamQuestion.SINGLE:
|
|
|
# 单选
|
|
|
PractiseAnswerOptionLog.objects.filter(main=answer_log).delete()
|
|
|
answer = answers[0]
|
|
|
PractiseAnswerOptionLog.objects.create(main=answer_log, option_id=answer)
|
|
|
- right = ExamQuestionOption.objects.filter(main=now_question, id=answer, right=True, delete=False )
|
|
|
+ right = ExamQuestionOption.objects.filter(main=now_question, id=answer, right=True,
|
|
|
+ delete=False)
|
|
|
if right:
|
|
|
- instance.right_count += 1
|
|
|
answer_log.status = PractiseAnswerLog.RIGHT
|
|
|
else:
|
|
|
answer_log.status = PractiseAnswerLog.WRONG
|
|
|
- instance.wrong_count += 1
|
|
|
elif now_question.type == ExamQuestion.MULTIPLE:
|
|
|
# 多选
|
|
|
answers.sort()
|
|
@@ -96,35 +96,30 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
list(right).sort()
|
|
|
if answers == right:
|
|
|
answer_log.status = PractiseAnswerLog.RIGHT
|
|
|
- instance.right_count += 1
|
|
|
else:
|
|
|
answer_log.status = PractiseAnswerLog.WRONG
|
|
|
- instance.wrong_count += 1
|
|
|
elif now_question.type == ExamQuestion.FILL:
|
|
|
# 填空
|
|
|
answers_len = len(answers)
|
|
|
right = 1
|
|
|
PractiseAnswerFillLog.objects.filter(main=answer_log).delete()
|
|
|
for a in range(0, answers_len):
|
|
|
- PractiseAnswerFillLog.objects.create(main=answer_log, content=answers[a], order=a+1)
|
|
|
- right_answer = ExamQuestionFill.objects.filter(main=now_question, content=answers[a], order=a+1)
|
|
|
+ PractiseAnswerFillLog.objects.create(main=answer_log, content=answers[a], order=a + 1)
|
|
|
+ right_answer = ExamQuestionFill.objects.filter(main=now_question, content=answers[a],
|
|
|
+ order=a + 1)
|
|
|
if not right_answer:
|
|
|
# 有一个填空错误,整题错误
|
|
|
right = 0
|
|
|
if right:
|
|
|
answer_log.status = PractiseAnswerLog.RIGHT
|
|
|
- instance.right_count += 1
|
|
|
else:
|
|
|
answer_log.status = PractiseAnswerLog.WRONG
|
|
|
- instance.wrong_count += 1
|
|
|
else:
|
|
|
# 判断
|
|
|
if now_question.judgment == (answers[0] == 1):
|
|
|
answer_log.status = PractiseAnswerLog.RIGHT
|
|
|
- instance.right_count += 1
|
|
|
else:
|
|
|
answer_log.status = PractiseAnswerLog.WRONG
|
|
|
- instance.wrong_count += 1
|
|
|
instance.total_count += 1
|
|
|
# 第一题
|
|
|
if not instance.begin_answer:
|
|
@@ -133,6 +128,16 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
instance.submit_time = timezone.now()
|
|
|
instance.save()
|
|
|
answer_log.save()
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ answer_log = PractiseAnswerLog.objects.get(main=instance, question=now_question, )
|
|
|
+ PractiseAnswerOptionLog.objects.filter(main=answer_log).delete()
|
|
|
+ PractiseAnswerFillLog.objects.filter(main=answer_log).delete()
|
|
|
+ answer_log.status = None
|
|
|
+ answer_log.save()
|
|
|
+ except PractiseAnswerLog.DoesNotExist:
|
|
|
+ # traceback.print_exc()
|
|
|
+ pass
|
|
|
|
|
|
question_data = {}
|
|
|
if instance.type == PractiseLog.SUBJECT:
|
|
@@ -140,7 +145,6 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
'type')
|
|
|
else:
|
|
|
questions = ExamQuestion.objects.filter(chapter=instance.chapter, delete=False).order_by('type')
|
|
|
-
|
|
|
# 返回下一题
|
|
|
if next_practise:
|
|
|
question = questions.filter(id=next_practise).first()
|
|
@@ -149,77 +153,80 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
question = questions.filter().first()
|
|
|
|
|
|
if question:
|
|
|
- question_data = {
|
|
|
- 'id': question.id,
|
|
|
- 'title': question.title,
|
|
|
- 'next_type': question.type, # 下一题习题类别
|
|
|
- 'next_number': next_number + 1, # 下下一题序号,
|
|
|
- 'option': [],
|
|
|
+ question_data = {
|
|
|
+ 'id': question.id,
|
|
|
+ 'title': question.title,
|
|
|
+ 'next_type': question.type, # 下一题习题类别
|
|
|
+ 'next_number': int(next_number) + 1, # 下下一题序号,
|
|
|
+ 'option': [],
|
|
|
+ }
|
|
|
+ answer_log = PractiseAnswerLog.objects.filter(main=instance, question=question).first()
|
|
|
+ if question.type == ExamQuestion.JUDGMENT:
|
|
|
+ item1 = {
|
|
|
+ 'id': 1,
|
|
|
+ 'content': '正确',
|
|
|
+ 'answer': True if answer_log and answer_log.status == PractiseAnswerLog.RIGHT else False
|
|
|
}
|
|
|
- answer_log = PractiseAnswerLog.objects.filter(main=instance, question=question).first()
|
|
|
- if question.type == ExamQuestion.JUDGMENT:
|
|
|
- item1 = {
|
|
|
- 'id': 1,
|
|
|
- 'content': '正确',
|
|
|
- 'answer': True if answer_log and answer_log.status == PractiseAnswerLog.RIGHT else False
|
|
|
+ item0 = {
|
|
|
+ 'id': 0,
|
|
|
+ 'content': '错误',
|
|
|
+ 'answer': True if answer_log and answer_log.status == PractiseAnswerLog.WRONG else False
|
|
|
+ }
|
|
|
+ question_data['option'].append(item1)
|
|
|
+ question_data['option'].append(item0)
|
|
|
+ elif question.type <= ExamQuestion.MULTIPLE:
|
|
|
+ rows = ExamQuestionOption.objects.filter(main=question, delete=False)
|
|
|
+ for row in rows:
|
|
|
+ option_log = PractiseAnswerOptionLog.objects.filter(main=answer_log, option=row).first()
|
|
|
+ item = {
|
|
|
+ 'id': row.id,
|
|
|
+ 'content': row.content,
|
|
|
+ 'answer': option_log and True or False
|
|
|
}
|
|
|
- item0 = {
|
|
|
- 'id': 0,
|
|
|
- 'content': '错误',
|
|
|
- 'answer': True if answer_log and answer_log.status == PractiseAnswerLog.WRONG else False
|
|
|
+ question_data['option'].append(item)
|
|
|
+ elif question.type == ExamQuestion.FILL:
|
|
|
+ rows = ExamQuestionFill.objects.filter(main=question, delete=False)
|
|
|
+ for row in rows:
|
|
|
+ option_log = PractiseAnswerFillLog.objects.filter(main=answer_log, order=row.order).first()
|
|
|
+ item = {
|
|
|
+ 'id': row.order, # 填空题序号
|
|
|
+ 'content': option_log and option_log.content or '',
|
|
|
}
|
|
|
- question_data['option'].append(item1)
|
|
|
- question_data['option'].append(item0)
|
|
|
- elif question.type <= ExamQuestion.MULTIPLE:
|
|
|
- rows = ExamQuestionOption.objects.filter(main=question, delete=False)
|
|
|
- for row in rows:
|
|
|
- option_log = PractiseAnswerOptionLog.objects.filter(main=answer_log, option=row).first()
|
|
|
- item = {
|
|
|
- 'id':row.id,
|
|
|
- 'content':row.content,
|
|
|
- 'answer': option_log and True or False
|
|
|
- }
|
|
|
- question_data['option'].append(item)
|
|
|
- elif question.type == ExamQuestion.FILL:
|
|
|
- rows = ExamQuestionFill.objects.filter(main=question, delete=False)
|
|
|
- for row in rows:
|
|
|
- option_log = PractiseAnswerFillLog.objects.filter(main=answer_log, order=row.order).first()
|
|
|
- item = {
|
|
|
- 'id':row.order, # 填空题序号
|
|
|
- 'content':option_log and option_log.content or '',
|
|
|
- }
|
|
|
- question_data['option'].append(item)
|
|
|
+ question_data['option'].append(item)
|
|
|
|
|
|
# 右侧习题类别列表
|
|
|
# 单选题
|
|
|
+ # 单选、多选、填空。选择答案后,可能会把答案清空,得加上status__isnull=False过滤
|
|
|
questions = questions.values_list('id', flat=True)
|
|
|
single_questions_list = []
|
|
|
for single in questions.filter(type=ExamQuestion.SINGLE):
|
|
|
- answer_log = PractiseAnswerLog.objects.filter(main=instance, question_id=single)
|
|
|
+ answer_log = PractiseAnswerLog.objects.filter(main=instance, question_id=single,
|
|
|
+ status__isnull=False)
|
|
|
single_questions_list.append(
|
|
|
{
|
|
|
- 'question_id':single,
|
|
|
- 'complete':answer_log and True or False,
|
|
|
+ 'question_id': single,
|
|
|
+ 'complete': answer_log and True or False,
|
|
|
}
|
|
|
)
|
|
|
# 多选题
|
|
|
multiple_questions_list = []
|
|
|
for multiple in questions.filter(type=ExamQuestion.MULTIPLE):
|
|
|
- answer_log = PractiseAnswerLog.objects.filter(main=instance, question_id=multiple)
|
|
|
+ answer_log = PractiseAnswerLog.objects.filter(main=instance, question_id=multiple,
|
|
|
+ status__isnull=False)
|
|
|
multiple_questions_list.append(
|
|
|
{
|
|
|
- 'question_id':multiple,
|
|
|
- 'complete':answer_log and True or False,
|
|
|
+ 'question_id': multiple,
|
|
|
+ 'complete': answer_log and True or False,
|
|
|
}
|
|
|
)
|
|
|
# 填空题
|
|
|
fill_questions_list = []
|
|
|
for fill in questions.filter(type=ExamQuestion.FILL):
|
|
|
- answer_log = PractiseAnswerLog.objects.filter(main=instance, question_id=fill)
|
|
|
+ answer_log = PractiseAnswerLog.objects.filter(main=instance, question_id=fill, status__isnull=False)
|
|
|
fill_questions_list.append(
|
|
|
{
|
|
|
- 'question_id':fill,
|
|
|
- 'complete':answer_log and True or False,
|
|
|
+ 'question_id': fill,
|
|
|
+ 'complete': answer_log and True or False,
|
|
|
}
|
|
|
)
|
|
|
# 判断题
|
|
@@ -228,8 +235,8 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
answer_log = PractiseAnswerLog.objects.filter(main=instance, question_id=judgment)
|
|
|
judgment_questions_list.append(
|
|
|
{
|
|
|
- 'question_id':judgment,
|
|
|
- 'complete':answer_log and True or False,
|
|
|
+ 'question_id': judgment,
|
|
|
+ 'complete': answer_log and True or False,
|
|
|
}
|
|
|
)
|
|
|
result = {
|
|
@@ -246,6 +253,27 @@ class PractiseLogViewSet(CustomModelViewSet):
|
|
|
traceback.print_exc()
|
|
|
return response_error(str(e))
|
|
|
|
|
|
+ @action(methods=['post'], detail=True)
|
|
|
+ def submit_practise(self, request, pk):
|
|
|
+ # 习题交卷,把上个接口的判断答案,放到此处
|
|
|
+ try:
|
|
|
+ instance = self.get_object()
|
|
|
+
|
|
|
+ with transaction.atomic():
|
|
|
+ right_count = PractiseAnswerLog.objects.filter(main=instance, status=PractiseAnswerLog.RIGHT).count()
|
|
|
+ wrong_count = PractiseAnswerLog.objects.filter(main=instance, status=PractiseAnswerLog.WRONG).count()
|
|
|
+ instance.right_count = right_count
|
|
|
+ instance.wrong_count = wrong_count
|
|
|
+ instance.submit_time = timezone.now()
|
|
|
+ instance.save()
|
|
|
+ SysLog.objects.addnew(request.user, SysLog.INSERT, u"提交习题答案,id=%d" % (instance.id))
|
|
|
+ except CustomError as e:
|
|
|
+ return response_error(e.get_error_msg())
|
|
|
+ except Exception as e:
|
|
|
+ traceback.print_exc()
|
|
|
+ return response_error(str(e))
|
|
|
+ return response_ok()
|
|
|
+
|
|
|
class DictView(APIView):
|
|
|
permission_classes = [IsStaff, ]
|
|
|
|