models.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # coding=utf-8
  2. import random
  3. from django.db import models
  4. from django.utils import timezone
  5. from django.conf import settings
  6. from utils.exceptions import CustomError
  7. from apps.foundation.models import Subject
  8. from apps.examination.examquestion.models import ExamQuestion
  9. class ExamPaper(models.Model):
  10. MOCK = 1
  11. FORMAL = 2
  12. RANDOM = 3
  13. TYPE_CHOICES = (
  14. (MOCK, u'模拟试卷'),
  15. (FORMAL, u'正式试卷'),
  16. (RANDOM, u'随机试卷'),
  17. )
  18. TYPE_JSON = [{'id': item[0], 'value': item[1]} for item in TYPE_CHOICES]
  19. name = models.CharField(max_length=200, verbose_name=u"名称")
  20. subject = models.ForeignKey(Subject, verbose_name=u"科目", on_delete=models.PROTECT)
  21. type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=u"类型")
  22. passline = models.IntegerField(verbose_name=u'及格线')
  23. desc = models.TextField(verbose_name=u"备注", null=True, blank=True)
  24. single_simple_count = models.IntegerField(verbose_name=u'简单单选题数量', default=0)
  25. multiple_simple_count = models.IntegerField(verbose_name=u'简单多选题数量', default=0)
  26. fill_simple_count = models.IntegerField(verbose_name=u'简单填空题数量', default=0)
  27. judgment_simple_count = models.IntegerField(verbose_name=u'简单判断题数量', default=0)
  28. single_mid_count = models.IntegerField(verbose_name=u'中等单选题数量', default=0)
  29. multiple_mid_count = models.IntegerField(verbose_name=u'中等多选题数量', default=0)
  30. fill_mid_count = models.IntegerField(verbose_name=u'中等填空题数量', default=0)
  31. judgment_mid_count = models.IntegerField(verbose_name=u'中等判断题数量', default=0)
  32. single_hard_count = models.IntegerField(verbose_name=u'困难单选题数量', default=0)
  33. multiple_hard_count = models.IntegerField(verbose_name=u'困难多选题数量', default=0)
  34. fill_hard_count = models.IntegerField(verbose_name=u'困难填空题数量', default=0)
  35. judgment_hard_count = models.IntegerField(verbose_name=u'困难判断题数量', default=0)
  36. single_scores = models.IntegerField(verbose_name=u'单选题单题分数', default=0)
  37. multiple_scores = models.IntegerField(verbose_name=u'多选题单题分数', default=0)
  38. fill_scores = models.IntegerField(verbose_name=u'填空题单题分数', default=0)
  39. judgment_scores = models.IntegerField(verbose_name=u'判断题单题分数', default=0)
  40. single_total_count = models.IntegerField(verbose_name=u'单选题总数量', default=0, editable=False)
  41. multiple_total_count = models.IntegerField(verbose_name=u'多选题总数量', default=0, editable=False)
  42. fill_total_count = models.IntegerField(verbose_name=u'填空题总数量', default=0, editable=False)
  43. judgment_total_count = models.IntegerField(verbose_name=u'判断题总数量', default=0, editable=False)
  44. single_total_scores = models.IntegerField(verbose_name=u'单选题总分数', default=0, editable=False)
  45. multiple_total_scores = models.IntegerField(verbose_name=u'多选题总分数', default=0, editable=False)
  46. fill_total_scores = models.IntegerField(verbose_name=u'填空题总分数', default=0, editable=False)
  47. judgment_total_scores = models.IntegerField(verbose_name=u'判断题总分数', default=0, editable=False)
  48. question_total_count = models.IntegerField(verbose_name=u'试题总数量', default=0, editable=False)
  49. question_total_scores = models.IntegerField(verbose_name=u'试题总分数', default=0, editable=False)
  50. create_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'添加人', editable=False, on_delete=models.PROTECT)
  51. create_time = models.DateTimeField(verbose_name=u"添加时间", default=timezone.now, editable=False)
  52. delete = models.BooleanField(verbose_name=u'删除', default=False, editable=False)
  53. did_count = models.IntegerField(verbose_name=u'做过人数', default=0, editable=False)
  54. class Meta:
  55. db_table = "exam_paper"
  56. ordering = ['-id']
  57. verbose_name = u"试卷管理"
  58. default_permissions = ()
  59. @staticmethod
  60. def getById(id):
  61. instance = ExamPaper.objects.filter(pk=id).first()
  62. if not instance:
  63. raise CustomError(u'未找到相应的试卷')
  64. return instance
  65. def generate_passline(self):
  66. self.passline = int(self.question_total_scores * 0.6)
  67. def clear_detail(self):
  68. ExamPaperDetail.objects.filter(main=self).update(delete=True)
  69. def generate_detail(self):
  70. begin_order = 1
  71. if self.single_simple_count:
  72. self._generate_detail(self.single_simple_count, ExamQuestion.SINGLE, ExamQuestion.SIMPLE, begin_order)
  73. begin_order += self.single_simple_count
  74. if self.single_mid_count:
  75. self._generate_detail(self.single_mid_count, ExamQuestion.SINGLE, ExamQuestion.MID, begin_order)
  76. begin_order += self.single_mid_count
  77. if self.single_hard_count:
  78. self._generate_detail(self.single_hard_count, ExamQuestion.SINGLE, ExamQuestion.HARD, begin_order)
  79. begin_order += self.single_hard_count
  80. if self.multiple_simple_count:
  81. self._generate_detail(self.multiple_simple_count, ExamQuestion.MULTIPLE, ExamQuestion.SIMPLE, begin_order)
  82. begin_order += self.multiple_simple_count
  83. if self.multiple_mid_count:
  84. self._generate_detail(self.multiple_mid_count, ExamQuestion.MULTIPLE, ExamQuestion.MID, begin_order)
  85. begin_order += self.multiple_mid_count
  86. if self.multiple_hard_count:
  87. self._generate_detail(self.multiple_hard_count, ExamQuestion.MULTIPLE, ExamQuestion.HARD, begin_order)
  88. begin_order += self.multiple_hard_count
  89. if self.fill_simple_count:
  90. self._generate_detail(self.fill_simple_count, ExamQuestion.FILL, ExamQuestion.SIMPLE, begin_order)
  91. begin_order += self.fill_simple_count
  92. if self.fill_mid_count:
  93. self._generate_detail(self.fill_mid_count, ExamQuestion.FILL, ExamQuestion.MID, begin_order)
  94. begin_order += self.fill_mid_count
  95. if self.fill_hard_count:
  96. self._generate_detail(self.fill_hard_count, ExamQuestion.FILL, ExamQuestion.HARD, begin_order)
  97. begin_order += self.fill_hard_count
  98. if self.judgment_simple_count:
  99. self._generate_detail(self.judgment_simple_count, ExamQuestion.JUDGMENT, ExamQuestion.SIMPLE, begin_order)
  100. begin_order += self.judgment_simple_count
  101. if self.judgment_mid_count:
  102. self._generate_detail(self.judgment_mid_count, ExamQuestion.JUDGMENT, ExamQuestion.MID, begin_order)
  103. begin_order += self.judgment_mid_count
  104. if self.judgment_hard_count:
  105. self._generate_detail(self.judgment_hard_count, ExamQuestion.JUDGMENT, ExamQuestion.HARD, begin_order)
  106. begin_order += self.judgment_hard_count
  107. def update_count(self):
  108. self.single_total_count = self.single_simple_count + self.single_mid_count + self.single_hard_count
  109. self.multiple_total_count = self.multiple_simple_count + self.multiple_mid_count + self.multiple_hard_count
  110. self.fill_total_count = self.fill_simple_count + self.fill_mid_count + self.fill_hard_count
  111. self.judgment_total_count = self.judgment_simple_count + self.judgment_mid_count + self.judgment_hard_count
  112. self.single_total_scores = self.single_scores * self.single_total_count
  113. self.multiple_total_scores = self.multiple_scores * self.multiple_total_count
  114. self.fill_total_scores = self.fill_scores * self.fill_total_count
  115. self.judgment_total_scores = self.judgment_scores * self.judgment_total_count
  116. self.question_total_count = self.single_total_count + self.multiple_total_count + self.fill_total_count + self.judgment_total_count
  117. self.question_total_scores = self.single_total_scores + self.multiple_total_scores + self.fill_total_scores + self.judgment_total_scores
  118. return self
  119. def _generate_detail(self, count, type, difficulty, begin_order):
  120. questions = ExamQuestion.objects.filter(
  121. chapter__subject=self.subject,
  122. difficulty = difficulty,
  123. type = type,
  124. delete=False
  125. )
  126. questions_count = questions.count()
  127. if questions_count < count:
  128. raise CustomError(u'[%s][%s]数量不足!' % (ExamQuestion.DIFFICULTY_CHOICES[difficulty-1][1], ExamQuestion.TYPE_CHOICES[type-1][1]))
  129. question_ids = questions.values_list('id', flat=True)
  130. rows = random.sample(list(question_ids), count)
  131. random.shuffle(rows)
  132. data = []
  133. for row in rows:
  134. item = ExamPaperDetail(
  135. main=self,
  136. question_id=row,
  137. order=begin_order
  138. )
  139. begin_order += 1
  140. data.append(item)
  141. ExamPaperDetail.objects.bulk_create(data)
  142. class ExamPaperDetail(models.Model):
  143. main = models.ForeignKey(ExamPaper, verbose_name=u"试卷", on_delete=models.PROTECT)
  144. question = models.ForeignKey(ExamQuestion, verbose_name=u"试题", on_delete=models.PROTECT)
  145. order = models.IntegerField(verbose_name=u'序号', editable=False)
  146. delete = models.BooleanField(verbose_name=u'删除', default=False, editable=False)
  147. class Meta:
  148. db_table = "exam_paper_detail"
  149. ordering = ['order']
  150. verbose_name = u"试卷明细"
  151. default_permissions = ()