models.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. discuss_simple_count = models.IntegerField(verbose_name=u'简单论述题数量', default=0)
  29. single_mid_count = models.IntegerField(verbose_name=u'中等单选题数量', default=0)
  30. multiple_mid_count = models.IntegerField(verbose_name=u'中等多选题数量', default=0)
  31. fill_mid_count = models.IntegerField(verbose_name=u'中等填空题数量', default=0)
  32. judgment_mid_count = models.IntegerField(verbose_name=u'中等判断题数量', default=0)
  33. discuss_mid_count = models.IntegerField(verbose_name=u'中等论述题数量', default=0)
  34. single_hard_count = models.IntegerField(verbose_name=u'困难单选题数量', default=0)
  35. multiple_hard_count = models.IntegerField(verbose_name=u'困难多选题数量', default=0)
  36. fill_hard_count = models.IntegerField(verbose_name=u'困难填空题数量', default=0)
  37. judgment_hard_count = models.IntegerField(verbose_name=u'困难判断题数量', default=0)
  38. discuss_hard_count = models.IntegerField(verbose_name=u'困难论述题数量', default=0)
  39. single_scores = models.IntegerField(verbose_name=u'单选题单题分数', default=0)
  40. multiple_scores = models.IntegerField(verbose_name=u'多选题单题分数', default=0)
  41. fill_scores = models.IntegerField(verbose_name=u'填空题单题分数', default=0)
  42. judgment_scores = models.IntegerField(verbose_name=u'判断题单题分数', default=0)
  43. discuss_scores = models.IntegerField(verbose_name=u'论述题单题分数', default=0)
  44. single_total_count = models.IntegerField(verbose_name=u'单选题总数量', default=0, editable=False)
  45. multiple_total_count = models.IntegerField(verbose_name=u'多选题总数量', default=0, editable=False)
  46. fill_total_count = models.IntegerField(verbose_name=u'填空题总数量', default=0, editable=False)
  47. judgment_total_count = models.IntegerField(verbose_name=u'判断题总数量', default=0, editable=False)
  48. discuss_total_count = models.IntegerField(verbose_name=u'论述题总数量', default=0, editable=False)
  49. single_total_scores = models.IntegerField(verbose_name=u'单选题总分数', default=0, editable=False)
  50. multiple_total_scores = models.IntegerField(verbose_name=u'多选题总分数', default=0, editable=False)
  51. fill_total_scores = models.IntegerField(verbose_name=u'填空题总分数', default=0, editable=False)
  52. judgment_total_scores = models.IntegerField(verbose_name=u'判断题总分数', default=0, editable=False)
  53. discuss_total_scores = models.IntegerField(verbose_name=u'论述题总分数', default=0, editable=False)
  54. question_total_count = models.IntegerField(verbose_name=u'试题总数量', default=0, editable=False)
  55. question_total_scores = models.IntegerField(verbose_name=u'试题总分数', default=0, editable=False)
  56. create_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'添加人', editable=False, on_delete=models.PROTECT)
  57. create_time = models.DateTimeField(verbose_name=u"添加时间", default=timezone.now, editable=False)
  58. delete = models.BooleanField(verbose_name=u'删除', default=False, editable=False)
  59. did_count = models.IntegerField(verbose_name=u'做过人数', default=0, editable=False)
  60. class Meta:
  61. db_table = "exam_paper"
  62. ordering = ['-id']
  63. verbose_name = u"试卷管理"
  64. default_permissions = ()
  65. @staticmethod
  66. def getById(id):
  67. instance = ExamPaper.objects.filter(pk=id).first()
  68. if not instance:
  69. raise CustomError(u'未找到相应的试卷')
  70. return instance
  71. def generate_passline(self):
  72. self.passline = int(self.question_total_scores * 0.6)
  73. def clear_detail(self):
  74. ExamPaperDetail.objects.filter(main=self).update(delete=True)
  75. def generate_detail(self):
  76. begin_order = 1
  77. if self.single_simple_count:
  78. self._generate_detail(self.single_simple_count, ExamQuestion.SINGLE, ExamQuestion.SIMPLE, begin_order)
  79. begin_order += self.single_simple_count
  80. if self.single_mid_count:
  81. self._generate_detail(self.single_mid_count, ExamQuestion.SINGLE, ExamQuestion.MID, begin_order)
  82. begin_order += self.single_mid_count
  83. if self.single_hard_count:
  84. self._generate_detail(self.single_hard_count, ExamQuestion.SINGLE, ExamQuestion.HARD, begin_order)
  85. begin_order += self.single_hard_count
  86. if self.multiple_simple_count:
  87. self._generate_detail(self.multiple_simple_count, ExamQuestion.MULTIPLE, ExamQuestion.SIMPLE, begin_order)
  88. begin_order += self.multiple_simple_count
  89. if self.multiple_mid_count:
  90. self._generate_detail(self.multiple_mid_count, ExamQuestion.MULTIPLE, ExamQuestion.MID, begin_order)
  91. begin_order += self.multiple_mid_count
  92. if self.multiple_hard_count:
  93. self._generate_detail(self.multiple_hard_count, ExamQuestion.MULTIPLE, ExamQuestion.HARD, begin_order)
  94. begin_order += self.multiple_hard_count
  95. if self.fill_simple_count:
  96. self._generate_detail(self.fill_simple_count, ExamQuestion.FILL, ExamQuestion.SIMPLE, begin_order)
  97. begin_order += self.fill_simple_count
  98. if self.fill_mid_count:
  99. self._generate_detail(self.fill_mid_count, ExamQuestion.FILL, ExamQuestion.MID, begin_order)
  100. begin_order += self.fill_mid_count
  101. if self.fill_hard_count:
  102. self._generate_detail(self.fill_hard_count, ExamQuestion.FILL, ExamQuestion.HARD, begin_order)
  103. begin_order += self.fill_hard_count
  104. if self.judgment_simple_count:
  105. self._generate_detail(self.judgment_simple_count, ExamQuestion.JUDGMENT, ExamQuestion.SIMPLE, begin_order)
  106. begin_order += self.judgment_simple_count
  107. if self.judgment_mid_count:
  108. self._generate_detail(self.judgment_mid_count, ExamQuestion.JUDGMENT, ExamQuestion.MID, begin_order)
  109. begin_order += self.judgment_mid_count
  110. if self.judgment_hard_count:
  111. self._generate_detail(self.judgment_hard_count, ExamQuestion.JUDGMENT, ExamQuestion.HARD, begin_order)
  112. begin_order += self.judgment_hard_count
  113. if self.discuss_simple_count:
  114. self._generate_detail(self.discuss_simple_count, ExamQuestion.DISCUSS, ExamQuestion.SIMPLE, begin_order)
  115. begin_order += self.discuss_simple_count
  116. if self.discuss_mid_count:
  117. self._generate_detail(self.discuss_mid_count, ExamQuestion.DISCUSS, ExamQuestion.MID, begin_order)
  118. begin_order += self.discuss_mid_count
  119. if self.discuss_hard_count:
  120. self._generate_detail(self.discuss_hard_count, ExamQuestion.DISCUSS, ExamQuestion.HARD, begin_order)
  121. begin_order += self.discuss_hard_count
  122. def update_count(self):
  123. self.single_total_count = self.single_simple_count + self.single_mid_count + self.single_hard_count
  124. self.multiple_total_count = self.multiple_simple_count + self.multiple_mid_count + self.multiple_hard_count
  125. self.fill_total_count = self.fill_simple_count + self.fill_mid_count + self.fill_hard_count
  126. self.judgment_total_count = self.judgment_simple_count + self.judgment_mid_count + self.judgment_hard_count
  127. self.discuss_total_count = self.discuss_simple_count + self.discuss_mid_count + self.discuss_hard_count
  128. self.single_total_scores = self.single_scores * self.single_total_count
  129. self.multiple_total_scores = self.multiple_scores * self.multiple_total_count
  130. self.fill_total_scores = self.fill_scores * self.fill_total_count
  131. self.judgment_total_scores = self.judgment_scores * self.judgment_total_count
  132. self.discuss_total_scores = self.discuss_scores * self.discuss_total_count
  133. self.question_total_count = self.single_total_count + self.multiple_total_count + self.fill_total_count + self.judgment_total_count + self.discuss_total_count
  134. self.question_total_scores = self.single_total_scores + self.multiple_total_scores + self.fill_total_scores + self.judgment_total_scores+ self.discuss_total_scores
  135. return self
  136. def _generate_detail(self, count, type, difficulty, begin_order):
  137. questions = ExamQuestion.objects.filter(
  138. chapter__subject=self.subject,
  139. difficulty = difficulty,
  140. type = type,
  141. delete=False
  142. )
  143. questions_count = questions.count()
  144. if questions_count < count:
  145. raise CustomError(u'[%s][%s]数量不足!' % (ExamQuestion.DIFFICULTY_CHOICES[difficulty-1][1], ExamQuestion.TYPE_CHOICES[type-1][1]))
  146. question_ids = questions.values_list('id', flat=True)
  147. rows = random.sample(list(question_ids), count)
  148. random.shuffle(rows)
  149. data = []
  150. for row in rows:
  151. item = ExamPaperDetail(
  152. main=self,
  153. question_id=row,
  154. order=begin_order
  155. )
  156. begin_order += 1
  157. data.append(item)
  158. ExamPaperDetail.objects.bulk_create(data)
  159. class ExamPaperDetail(models.Model):
  160. main = models.ForeignKey(ExamPaper, verbose_name=u"试卷", on_delete=models.PROTECT)
  161. question = models.ForeignKey(ExamQuestion, verbose_name=u"试题", on_delete=models.PROTECT)
  162. order = models.IntegerField(verbose_name=u'序号', editable=False)
  163. delete = models.BooleanField(verbose_name=u'删除', default=False, editable=False)
  164. class Meta:
  165. db_table = "exam_paper_detail"
  166. ordering = ['order']
  167. verbose_name = u"试卷明细"
  168. default_permissions = ()