From 47deee8567f0f2718a4a671f715cef17d5ae78e9 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 3 Nov 2022 17:40:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0paper=E8=A1=A8=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/exam/models.py | 86 ++++++++++++++++++++++++++++++++- server/apps/exam/serializers.py | 21 +++++++- server/apps/exam/views.py | 20 +++++++- 3 files changed, 123 insertions(+), 4 deletions(-) diff --git a/server/apps/exam/models.py b/server/apps/exam/models.py index bb71fd5..b86b5c2 100644 --- a/server/apps/exam/models.py +++ b/server/apps/exam/models.py @@ -1,6 +1,7 @@ from django.db import models from apps.system.models import CommonAModel from django.contrib.postgres.fields import JSONField +from utils.model import BaseModel # Create your models here. class Questioncat(CommonAModel): @@ -44,4 +45,87 @@ class Question(CommonAModel): verbose_name_plural = verbose_name def __str__(self): - return self.name \ No newline at end of file + return self.name + + +class Paper(CommonAModel): + name = models.CharField(max_length=200, verbose_name='名称') + questions = models.ManyToManyField(Question, through='PaperQuestions') + limit = models.IntegerField(default=0, verbose_name='限时(分钟)') + total_score = models.FloatField(default=0, verbose_name='满分') + pass_score = models.FloatField(default=0, verbose_name='及格分数') + danxuan_count = models.IntegerField(default=0, verbose_name='单选数量') + danxuan_score = models.FloatField(default=2, verbose_name='单选分数') + duoxuan_count = models.IntegerField(default=0, verbose_name='多选数量') + duoxuan_score = models.FloatField(default=4, verbose_name='多选分数') + panduan_count = models.IntegerField(default=0, verbose_name='判断数量') + panduan_score = models.FloatField(default=2, verbose_name='判断分数') + class Meta: + verbose_name = '押题卷' + verbose_name_plural = verbose_name + + def __str__(self): + return self.name + + +class PaperQuestions(BaseModel): + paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name='试卷') + question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name='试题') + total_score = models.FloatField(default=0, verbose_name='单题满分') + + +class Exam(CommonAModel): + """ + 组织的正式考试 + """ + code = models.CharField('考试编号', max_length=100, null=True, blank=True) + name = models.CharField('名称', max_length=100) + place = models.CharField('考试地点', max_length=100, null=True, blank=True) + open_time = models.DateTimeField('开启时间', null=True, blank=True) + close_time = models.DateTimeField('关闭时间', null=True, blank=True) + proctor_name = models.CharField('监考人姓名', max_length=100, null=True, blank=True) + proctor_phone = models.CharField('监考人联系方式', max_length=100, null=True, blank=True) + chance = models.IntegerField('考试机会', default=3) + paper = models.ForeignKey(Paper, verbose_name='使用的试卷', on_delete=models.CASCADE, null=True, blank=True) + + def __str__(self): + return self.name + +class ExamTest(CommonAModel): + ''' + 考试记录表 + ''' + type_choices = ( + ('自助模考', '自助模考'), + ('押卷模考', '押卷模考'), + ('正式考试', '正式考试') + ) + name = models.CharField(max_length=200, verbose_name='名称') + type = models.CharField(max_length=50, default='自助模考',choices = type_choices, verbose_name='考试类型') + limit = models.IntegerField(default=0, verbose_name='限时(分钟)') + paper = models.ForeignKey(Paper, on_delete=models.SET_NULL, verbose_name='所用试卷', null=True, blank=True) + total_score = models.FloatField(default=0, verbose_name='总分') + score = models.FloatField(default=0, verbose_name='得分') + took = models.IntegerField(default=0, verbose_name='耗时(秒)') + start_time = models.DateTimeField(verbose_name='开始答题时间') + end_time = models.DateTimeField(verbose_name='结束答题时间') + detail = models.ManyToManyField(Question, verbose_name='答题记录', through='AnswerDetail') + is_pass = models.BooleanField(default=True, verbose_name='是否通过') + exam = models.ForeignKey(Exam, verbose_name='关联的正式考试', null=True, blank=True, related_name='examtest_exam', on_delete= models.SET_NULL) + + class Meta: + verbose_name = '模拟考试' + verbose_name_plural = verbose_name + + + +class AnswerDetail(BaseModel): + examtest = models.ForeignKey(ExamTest, on_delete=models.CASCADE, related_name='answerdetail_examtest') + question = models.ForeignKey(Question, on_delete=models.CASCADE) + user_answer = JSONField(null=True,blank=True) + score = models.FloatField(default=0, verbose_name='本题得分') + is_right = models.BooleanField(default=False, verbose_name='是否正确') + + class Meta: + verbose_name = '答题记录' + verbose_name_plural = verbose_name \ No newline at end of file diff --git a/server/apps/exam/serializers.py b/server/apps/exam/serializers.py index 5363655..765ddfd 100644 --- a/server/apps/exam/serializers.py +++ b/server/apps/exam/serializers.py @@ -1,6 +1,6 @@ -from rest_framework.serializers import ModelSerializer +from rest_framework.serializers import ModelSerializer, CharField -from apps.exam.models import Question, Questioncat +from apps.exam.models import Question, Questioncat, Paper, Exam class QuestioncatSerializer(ModelSerializer): @@ -12,4 +12,21 @@ class QuestioncatSerializer(ModelSerializer): class QuestionSerializer(ModelSerializer): class Meta: model = Question + fields = '__all__' + + +class PaperSerializer(ModelSerializer): + class Meta: + model = Paper + exclude = ('questions',) + +class ExamCreateUpdateSerializer(ModelSerializer): + class Meta: + model = Exam + fields = ['name', 'place', 'open_time', 'close_time', 'proctor_name', 'proctor_phone'] + +class ExamListSerializer(ModelSerializer): + create_by_name = CharField(source='create_by.name', read_only=True) + class Meta: + model = Exam fields = '__all__' \ No newline at end of file diff --git a/server/apps/exam/views.py b/server/apps/exam/views.py index 4b9ba88..04ab1ee 100644 --- a/server/apps/exam/views.py +++ b/server/apps/exam/views.py @@ -2,12 +2,13 @@ from django.shortcuts import render from rest_framework.viewsets import ModelViewSet from apps.exam.exports import export_question from apps.exam.models import Question, Questioncat -from apps.exam.serializers import QuestionSerializer, QuestioncatSerializer +from apps.exam.serializers import QuestionSerializer, QuestioncatSerializer, PaperSerializer from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from openpyxl import Workbook, load_workbook from django.conf import settings +from apps.exam.models import Paper # Create your views here. @@ -167,3 +168,20 @@ class QuestionViewSet(ModelViewSet): obj.save() i = i + 1 return Response(notinlist, status=200) + + +class PaperViewSet(ModelViewSet): + """ + 试卷增删改查 + """ + perms_map = {'*': '*'} + queryset = Paper.objects.all() + serializer_class = PaperSerializer + ordering = ['id'] + search_fields = ('name',) + + +class ExamViewSet(ModelViewSet): + perms_map = {'*': '*'} + ordering = ['-id'] + search_fields = ('name',) \ No newline at end of file