This commit is contained in:
shijing 2022-11-14 17:01:51 +08:00
commit 9cf752bb1c
4 changed files with 33 additions and 12 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2022-11-14 03:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('exam', '0003_auto_20221108_0901'),
]
operations = [
migrations.AlterField(
model_name='examrecord',
name='end_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='结束答题时间'),
),
]

View File

@ -108,7 +108,7 @@ class ExamRecord(CommonAModel):
score = models.FloatField(default=0, verbose_name='得分') score = models.FloatField(default=0, verbose_name='得分')
took = models.IntegerField(default=0, verbose_name='耗时(秒)') took = models.IntegerField(default=0, verbose_name='耗时(秒)')
start_time = models.DateTimeField(verbose_name='开始答题时间') start_time = models.DateTimeField(verbose_name='开始答题时间')
end_time = models.DateTimeField(verbose_name='结束答题时间') end_time = models.DateTimeField(verbose_name='结束答题时间', null=True, blank=True)
detail = models.ManyToManyField(Question, verbose_name='答题记录', through='AnswerDetail') detail = models.ManyToManyField(Question, verbose_name='答题记录', through='AnswerDetail')
is_pass = models.BooleanField(default=True, verbose_name='是否通过') is_pass = models.BooleanField(default=True, verbose_name='是否通过')
exam = models.ForeignKey(Exam, verbose_name='关联的正式考试', null=True, blank=True, on_delete= models.SET_NULL) exam = models.ForeignKey(Exam, verbose_name='关联的正式考试', null=True, blank=True, on_delete= models.SET_NULL)

View File

@ -164,7 +164,7 @@ class AnswerDetailSerializer(ModelSerializer):
level = serializers.ReadOnlyField(source='question.level') level = serializers.ReadOnlyField(source='question.level')
class Meta: class Meta:
model = PaperQuestion model = AnswerDetail
fields = ['id', 'question', 'name', 'options', 'right', 'type', 'level', fields = ['id', 'question', 'name', 'options', 'right', 'type', 'level',
'total_score', 'questioncat_name', 'img', 'user_answer', 'score', 'is_right'] 'total_score', 'questioncat_name', 'img', 'user_answer', 'score', 'is_right']
@ -179,6 +179,6 @@ class AnswerDetailOutSerializer(ModelSerializer):
level = serializers.ReadOnlyField(source='question.level') level = serializers.ReadOnlyField(source='question.level')
class Meta: class Meta:
model = PaperQuestion model = AnswerDetail
fields = ['id', 'question', 'name', 'options', 'type', 'level', fields = ['id', 'question', 'name', 'options', 'type', 'level',
'total_score', 'questioncat_name', 'img', 'user_answer', 'score', 'is_right'] 'total_score', 'questioncat_name', 'img', 'user_answer', 'score', 'is_right']

View File

@ -1,6 +1,6 @@
from django.shortcuts import render from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet, GenericViewSet from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.mixins import ListModelMixin, DestroyModelMixin from rest_framework.mixins import ListModelMixin, DestroyModelMixin, RetrieveModelMixin
from apps.exam.exports import export_question from apps.exam.exports import export_question
from apps.exam.models import Question, Questioncat, PaperQuestion from apps.exam.models import Question, Questioncat, PaperQuestion
from apps.exam.serializers import (QuestionSerializer, QuestioncatSerializer, PaperSerializer, ExamDetailSerializer, ExamRecordDetailSerializer, ExamListSerializer, from apps.exam.serializers import (QuestionSerializer, QuestioncatSerializer, PaperSerializer, ExamDetailSerializer, ExamRecordDetailSerializer, ExamListSerializer,
@ -287,6 +287,7 @@ class ExamViewSet(CreateUpdateCustomMixin, ModelViewSet):
return Response(status=204) return Response(status=204)
@action(methods=['post'], detail=True, perms_map=[{'post': '*'}], serializer_class=Serializer, permission_classes = [IsAuthenticated]) @action(methods=['post'], detail=True, perms_map=[{'post': '*'}], serializer_class=Serializer, permission_classes = [IsAuthenticated])
@transaction.atomic
def start(self, request, *args, **kwargs): def start(self, request, *args, **kwargs):
""" """
开始考试 开始考试
@ -305,13 +306,14 @@ class ExamViewSet(CreateUpdateCustomMixin, ModelViewSet):
if exam.paper: if exam.paper:
er = ExamRecord() er = ExamRecord()
er.type = '正式考试' er.type = '正式考试'
er.name = '正式考试' + now.strftime('%Y%m%d%H%M') er.name = '正式考试' + datetime.now().strftime('%Y%m%d%H%M')
er.limit = exam.paper.limit er.limit = exam.paper.limit
er.paper = exam.paper er.paper = exam.paper
er.total_score = exam.paper.total_score er.total_score = exam.paper.total_score
er.start_time = now er.start_time = now
er.is_pass = False er.is_pass = False
er.exam = exam er.exam = exam
er.create_by = request.user
er.save() er.save()
ret = {} ret = {}
ret['examrecord'] = er.id ret['examrecord'] = er.id
@ -326,11 +328,11 @@ class ExamViewSet(CreateUpdateCustomMixin, ModelViewSet):
raise ParseError('暂不支持') raise ParseError('暂不支持')
class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, RetrieveModelMixin, GenericViewSet):
""" """
考试记录列表和详情 考试记录列表和详情
""" """
perms_map = {'get': 'examrecord', 'post': '*', 'delete':'examrecord'} perms_map = {'get': '*', 'post': '*', 'delete':'examrecord'}
queryset = ExamRecord.objects.select_related('create_by') queryset = ExamRecord.objects.select_related('create_by')
serializer_class = ExamRecordListSerializer serializer_class = ExamRecordListSerializer
ordering_fields = ['create_time', 'score', 'took', 'update_time'] ordering_fields = ['create_time', 'score', 'took', 'update_time']
@ -371,6 +373,7 @@ class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
return self.get_paginated_response(serializer.data) return self.get_paginated_response(serializer.data)
@action(methods=['post'], detail=True, perms_map=[{'post': '*'}], serializer_class=ExamRecordSubmitSerializer, permission_classes = [IsAuthenticated]) @action(methods=['post'], detail=True, perms_map=[{'post': '*'}], serializer_class=ExamRecordSubmitSerializer, permission_classes = [IsAuthenticated])
@transaction.atomic
def submit(self, request, pk=None): def submit(self, request, pk=None):
''' '''
提交答卷 提交答卷
@ -391,17 +394,17 @@ class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
vdata = serializer.validated_data vdata = serializer.validated_data
questions_ = vdata['questions_'] questions_ = vdata['questions_']
# 后端判卷 # 后端判卷
ads = AnswerDetail.objects.select_related('question').filter(examrecord=er).order_by('id').values('id', 'question__right', 'total_score', 'question__type') ads = AnswerDetail.objects.select_related('question').filter(examrecord=er).order_by('id')
total_score = 0 total_score = 0
try: try:
for index, ad in enumerate(ads): for index, ad in enumerate(ads):
ad.user_answer = questions_[index]['user_answer'] ad.user_answer = questions_[index]['user_answer']
if ad.question__type == '多选': if ad.question.type == '多选':
if set(ad.question__right) == set(ad.user_answer): if set(ad.question.right) == set(ad.user_answer):
ad.is_right = True ad.is_right = True
ad.score = ad.total_score ad.score = ad.total_score
else: else:
if ad.question__right == ad.user_answer: if ad.question.right == ad.user_answer:
ad.is_right = True ad.is_right = True
ad.score = ad.total_score ad.score = ad.total_score
ad.save() ad.save()
@ -415,4 +418,4 @@ class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
er.end_time = now er.end_time = now
er.is_submited = True er.is_submited = True
er.save() er.save()
return Response() return Response(ExamRecordListSerializer(instance=er).data)