diff --git a/apps/edu/migrations/0004_paper_type.py b/apps/edu/migrations/0004_paper_type.py new file mode 100644 index 00000000..05e622ff --- /dev/null +++ b/apps/edu/migrations/0004_paper_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2024-10-23 08:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('edu', '0003_alter_train_level'), + ] + + operations = [ + migrations.AddField( + model_name='paper', + name='type', + field=models.PositiveSmallIntegerField(choices=[(10, '固定试卷'), (20, '随机试卷')], default=10, verbose_name='类型'), + ), + ] diff --git a/apps/edu/models.py b/apps/edu/models.py index cee77945..952f09c4 100644 --- a/apps/edu/models.py +++ b/apps/edu/models.py @@ -4,39 +4,41 @@ from apps.system.models import User, Dept, File # Create your models here. -class Train(CommonADModel): +class Train(CommonADModel): T_L_POST = 10 T_L_TEAM = 20 T_L_DEPT = 30 T_L_COMPANY = 40 - level = models.PositiveSmallIntegerField(verbose_name='级别', choices=((T_L_POST, '岗位'), (T_L_TEAM, '班组'), (T_L_DEPT, '部门'), (T_L_COMPANY, '公司'))) - name = models.CharField(max_length=200, verbose_name='名称') - place = models.CharField(max_length=200, verbose_name='地点', default='', blank=True) - start_time = models.DateTimeField(verbose_name='开始时间') - end_time = models.DateTimeField(verbose_name='结束时间') - duration = models.PositiveIntegerField(verbose_name='时长', default=0, help_text='单位:s', editable=False) - description = models.TextField(verbose_name='内容描述', default='', blank=True) - is_public = models.BooleanField('是否公开', default=False) - files = models.ManyToManyField(File, verbose_name='附件', blank=True) - + level = models.PositiveSmallIntegerField(verbose_name="级别", choices=((T_L_POST, "岗位"), (T_L_TEAM, "班组"), (T_L_DEPT, "部门"), (T_L_COMPANY, "公司"))) + name = models.CharField(max_length=200, verbose_name="名称") + place = models.CharField(max_length=200, verbose_name="地点", default="", blank=True) + start_time = models.DateTimeField(verbose_name="开始时间") + end_time = models.DateTimeField(verbose_name="结束时间") + duration = models.PositiveIntegerField(verbose_name="时长", default=0, help_text="单位:s", editable=False) + description = models.TextField(verbose_name="内容描述", default="", blank=True) + is_public = models.BooleanField("是否公开", default=False) + files = models.ManyToManyField(File, verbose_name="附件", blank=True) + class Meta: - verbose_name = '线下培训' + verbose_name = "线下培训" verbose_name_plural = verbose_name + class Questioncat(CommonAModel): - name = models.CharField(max_length=200, verbose_name='名称') - parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='父级', related_name='cate_parent') - sort = models.PositiveIntegerField(default=0, verbose_name='排序') + name = models.CharField(max_length=200, verbose_name="名称") + parent = models.ForeignKey("self", on_delete=models.SET_NULL, null=True, blank=True, verbose_name="父级", related_name="cate_parent") + sort = models.PositiveIntegerField(default=0, verbose_name="排序") class Meta: - verbose_name = '题库分类' + verbose_name = "题库分类" verbose_name_plural = verbose_name def __str__(self): return self.name - + + class Question(CommonAModel): Q_DAN = 10 Q_DUO = 20 @@ -44,97 +46,106 @@ class Question(CommonAModel): Q_EASY = 10 Q_SIMPLE = 20 Q_HARD = 30 - name = models.TextField('题干') - img = models.TextField('题干图片', null=True, blank=True) - type = models.PositiveSmallIntegerField('题型', choices=((Q_DAN, '单选'), (Q_DUO, '多选'), (Q_PAN, '判断'))) - level = models.PositiveSmallIntegerField('难度', default=Q_SIMPLE, choices=((Q_EASY, '简单'), (Q_SIMPLE, '一般'), (Q_HARD, '困难'))) - questioncat = models.ForeignKey(Questioncat, blank=True, null=True, on_delete=models.SET_NULL, verbose_name='所属题库', related_name='questioncat') - options = models.JSONField('选项') - right = models.JSONField('正确答案') - resolution = models.TextField('解析', null=True, blank=True) - enabled = models.BooleanField('是否启用', default=False) + name = models.TextField("题干") + img = models.TextField("题干图片", null=True, blank=True) + type = models.PositiveSmallIntegerField("题型", choices=((Q_DAN, "单选"), (Q_DUO, "多选"), (Q_PAN, "判断"))) + level = models.PositiveSmallIntegerField("难度", default=Q_SIMPLE, choices=((Q_EASY, "简单"), (Q_SIMPLE, "一般"), (Q_HARD, "困难"))) + questioncat = models.ForeignKey(Questioncat, blank=True, null=True, on_delete=models.SET_NULL, verbose_name="所属题库", related_name="questioncat") + options = models.JSONField("选项") + right = models.JSONField("正确答案") + resolution = models.TextField("解析", null=True, blank=True) + enabled = models.BooleanField("是否启用", default=False) + class Meta: - verbose_name = '题目' + verbose_name = "题目" verbose_name_plural = verbose_name def __str__(self): return self.name - + class Paper(CommonAModel): - name = models.CharField(max_length=200, verbose_name='名称') - questions = models.ManyToManyField(Question, through='PaperQuestion') - 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='判断分数') + PAPER_FIX = 10 # 固定试卷 + PAPER_RANDOM = 20 # 自动抽题 + + name = models.CharField(max_length=200, verbose_name="名称") + type = models.PositiveSmallIntegerField("类型", default=10, choices=((PAPER_FIX, "固定试卷"), (PAPER_RANDOM, "随机试卷"))) + questions = models.ManyToManyField(Question, through="PaperQuestion") + 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 = "押题卷" verbose_name_plural = verbose_name def __str__(self): return self.name - + @property def detail(self): return PaperQuestion.objects.filter(paper=self) + class PaperQuestion(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='单题满分') - sort = models.IntegerField(default=0, verbose_name='排序') + 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="单题满分") + sort = models.IntegerField(default=0, verbose_name="排序") class Exam(CommonADModel): - name = models.CharField('名称', max_length=100) - open_time = models.DateTimeField('开启时间') - close_time = models.DateTimeField('关闭时间', null=True, blank=True) - chance = models.IntegerField('考试机会', default=1) # 0表示不限次数 - paper = models.ForeignKey(Paper, verbose_name='使用的试卷', on_delete=models.SET_NULL, null=True, blank=True) - is_public = models.BooleanField('是否公开', default=False) - p_users = models.ManyToManyField(User, verbose_name='指定用户', blank=True) - p_depts = models.ManyToManyField(Dept, verbose_name='指定部门', blank=True) + name = models.CharField("名称", max_length=100) + open_time = models.DateTimeField("开启时间") + close_time = models.DateTimeField("关闭时间", null=True, blank=True) + chance = models.IntegerField("考试机会", default=1) # 0表示不限次数 + paper = models.ForeignKey(Paper, verbose_name="使用的试卷", on_delete=models.SET_NULL, null=True, blank=True) + is_public = models.BooleanField("是否公开", default=False) + p_users = models.ManyToManyField(User, verbose_name="指定用户", blank=True) + p_depts = models.ManyToManyField(Dept, verbose_name="指定部门", blank=True) class Meta: - verbose_name = '在线考试' + verbose_name = "在线考试" verbose_name_plural = verbose_name def __str__(self): return self.name + class ExamRecord(CommonADModel): - ''' + """ 考试记录表 - ''' - exam = models.ForeignKey(Exam, on_delete=models.CASCADE, verbose_name='关联考试', related_name='record_exam') - 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='结束答题时间', null=True, blank=True) - questions = models.ManyToManyField(Question, verbose_name='答题记录', through='AnswerDetail') - is_pass = models.BooleanField(default=True, verbose_name='是否通过') - is_submited = models.BooleanField(default=False, verbose_name='是否提交') - is_last = models.BooleanField(default=False, verbose_name='是否最后一次考试记录') - + """ + + exam = models.ForeignKey(Exam, on_delete=models.CASCADE, verbose_name="关联考试", related_name="record_exam") + 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="结束答题时间", null=True, blank=True) + questions = models.ManyToManyField(Question, verbose_name="答题记录", through="AnswerDetail") + is_pass = models.BooleanField(default=True, verbose_name="是否通过") + is_submited = models.BooleanField(default=False, verbose_name="是否提交") + is_last = models.BooleanField(default=False, verbose_name="是否最后一次考试记录") + class Meta: - verbose_name = '考试记录' + verbose_name = "考试记录" verbose_name_plural = verbose_name class AnswerDetail(BaseModel): - examrecord = models.ForeignKey(ExamRecord, on_delete=models.CASCADE, related_name='detail_er') - total_score = models.FloatField(default=0, verbose_name='该题满分') + examrecord = models.ForeignKey(ExamRecord, on_delete=models.CASCADE, related_name="detail_er") + total_score = models.FloatField(default=0, verbose_name="该题满分") question = models.ForeignKey(Question, on_delete=models.CASCADE) - user_answer = models.JSONField(null=True,blank=True) - score = models.FloatField(default=0, verbose_name='本题得分') - is_right = models.BooleanField(default=False, verbose_name='是否正确') + user_answer = models.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 + verbose_name = "答题记录" + verbose_name_plural = verbose_name