text: from utils.api import APIView,validate_serializer
  
  from ..models import CourseAnnouncement, Course,UserCourse,Course_task,Taskproblem,TaskSmallproblem,CourseSubmission
  from problem.serializers import ProblemAdminSerializer,SmallProblemSerializer,ProblemSerializer
  from ..serializers import CourseAnnouncementSerializer,CourseSerializer,CourseTaskSerializer\
      ,CourseSubmissionModelSerializer,CourseSubmissionSafeModelSerializer,CreateCourseSubmissionSerializer
  from problem.models import Problem,SmallProblem,SmallJudgeStatus,ProblemRuleType
  import logging
  logger = logging.getLogger("django")
  from django.db import transaction#2018.3.15
  from utils.captcha import Captcha
  from utils.throttling import TokenBucket
  from utils.cache import cache
  from options.options import SysOptions
  #from judge.dispatcher import CourseJudgeDispatcher#开发环境
  from judge.tasks import judge_course#生产环境
  
  class CourseAnnouncementListAPI(APIView):
      def get(self, request):
          course_id = request.GET.get("course_id")
          if not course_id:
              return self.error("Invalid parameter, course_id is required")
          data = CourseAnnouncement.objects.select_related("created_by").filter(course_id=course_id, visible=True)
          return self.success(CourseAnnouncementSerializer(data, many=True).data)
  
  
  class CourseAPI(APIView):
      def post(self,request):
          data = request.data
          user = request.user
          try:
              course = Course.objects.get(code=data["code"])
          except Course.DoesNotExist:
              return self.error("课程不存在")
          user_courses = UserCourse.objects.filter(user=user)
          for user_course in user_courses:
              if user_course.course==course:
                  return self.error("该课程已加入...")
          with transaction.atomic():
              UserCourse.objects.create(user=user,course=course)
              course.total_student = course.total_student + 1
              course.save()
          return self.success()
  
      def get(self, request):
          user = request.user
          id = request.GET.get("course_id")#课程id
  
          if id:
              course = Course.objects.get(id=id)
              return self.success(CourseSerializer(course).data)
          userCourse = UserCourse.objects.filter(user=user)
          return self.success([CourseSerializer(data.course).data for data in userCourse])
  
      def delete(self,request):
          user = request.user
          course_id = request.GET.get("course_id")
          UserCourse.objects.filter(course_id=course_id,user=user).delete()
          return self.success()
  
  
  class CourseTaskAPI(APIView):
      def get(self,request):
          task_id = request.GET.get("task_id")
          if task_id:
              task = Course_task.objects.get(id=task_id)
              return self.success(CourseTaskSerializer(task).data)
  
          id = request.GET.get("course_id")  # 课程id
          task  = Course_task.objects.filter(course_id=id,visible=True)
          return self.success(CourseTaskSerializer(task,many=True).data)#如果是根据表连接查询得到的数据，要在上many=Ture.
  
  
  class CourseTaskProblemAPI(APIView):
      @staticmethod
      def _add_two_problem_status(request, queryset_values1,queryset_values2):
          if request.user.is_authenticated:
              user = request.user
              course_id = request.GET.get("course_id")
              task_id = request.GET.get("task_id")
              user_course = UserCourse.objects.get(course_id=course_id,user=user)
  
              for small_problem in queryset_values1:
                  small_problem["my_status"] = user_course.small_problem_status.get(str(task_id), {}).get(str(small_problem["id"]), {}).get("status")
                  small_problem["my_answer"] = user_course.small_problem_status.get(str(task_id), {}).get(str(small_problem["id"]), {}).get("answer")
              for problem in queryset_values2:
                  if problem["rule_type"] == ProblemRuleType.ACM:
                      problem["my_status"] = user_course.acm_problem_status.get(str(task_id), {}).get(str(problem["id"]), {}).get("status")
                  else:
                      problem["my_status"] = user_course.oi_problem_status.get(str(task_id), {}).get(str(problem["id"]), {}).get("status")
  
      @staticmethod
      def _add_problem_status(request, queryset_values):
          if request.user.is_authenticated:
              user = request.user
              course_id = request.GET.get("course_id")
              task_id = request.GET.get("task_id")
              user_course = UserCourse.objects.get(course_id=course_id,user=user)
  
              if queryset_values["rule_type"] == ProblemRuleType.ACM:
                  queryset_values["my_status"] = user_course.acm_problem_status.get(str(task_id), {}).get(str(queryset_values["id"]), {}).get("status")
              else:
                  queryset_values["my_status"] = user_course.oi_problem_status.get(str(task_id), {}).get(str(queryset_values["id"]), {}).get("status")
  
      def get(self,request):
          # 问题详情页
          problem_id = request.GET.get("problem_id")
          if problem_id:
              try:
                  problem = Problem.objects.select_related("created_by") \
                      .get(id=problem_id, is_public=True, visible=True)
                  problem_data = ProblemSerializer(problem).data#serializer序列化是把从数据库得到的QuerySet对象转化为python可以识别的dict数据类型
                  self._add_problem_status(request,problem_data)
                  return self.success(problem_data)
              except Problem.DoesNotExist:
                  return self.error("Problem does not exist")
          task_id = request.GET.get("task_id")
          task = Course_task.objects.get(id=task_id)
          problems = Taskproblem.objects.filter(task=task)
          small_problems =TaskSmallproblem.objects.filter(task=task)
          data1 = [SmallProblemSerializer(smallproblem.smallproblem).data for smallproblem in small_problems]
          data2 = [ProblemAdminSerializer(problem.problem).data for problem in problems]
          self._add_two_problem_status(request,data1,data2)
          return self.success_new(data1,data2)
  
  class JudgeSmallProblemAPI(APIView):#判断小题
      def post(self, request):
          data = request.data
          user_id = request.user.id
          problem_id = data["id"]
          course_id = data["course_id"]
          task_id = data["task_id"]
          my_answer = data["my_answer"]#用户答案
          small_problem = SmallProblem.objects.get(id=problem_id)
          if small_problem.answer == my_answer:
              result = SmallJudgeStatus.TRUE
          else:
              result = SmallJudgeStatus.FALSE
          #往user_course加小题做题状态
              # update_usercourse
          user_course = UserCourse.objects.get(course_id=course_id,user_id=user_id)
          small_problem_status = user_course.small_problem_status
          if task_id not in small_problem_status:
              small_problem_status[task_id]={}
          small_problem_status[task_id][problem_id] = {"status": result, "answer": my_answer}
          user_course.small_problems_status = small_problem_status
          user_course.save()
          return self.success({"my_status":result})
  
  class JudgeProblemAPI(APIView):#判断编程题
      def throttling(self, request):
          user_bucket = TokenBucket(key=str(request.user.id),
                                    redis_conn=cache, **SysOptions.throttling["user"])
          can_consume, wait = user_bucket.consume()
          if not can_consume:
              return "Please wait %d seconds" % (int(wait))
  
          ip_bucket = TokenBucket(key=request.session["ip"],
                                  redis_conn=cache, **SysOptions.throttling["ip"])
          can_consume, wait = ip_bucket.consume()
          if not can_consume:
              return "Captcha is required"
  
      @validate_serializer(CreateCourseSubmissionSerializer)
      def post(self, request):
          data = request.data
          hide_id = False
          course_id = data["course_id"]
          task_id = data["task_id"]
  
  
          if data.get("captcha"):
              if not Captcha(request).check(data["captcha"]):
                  return self.error("Invalid captcha")
          error = self.throttling(request)
          if error:
              return self.error(error)
  
          try:
              problem = Problem.objects.get(id=data["problem_id"], visible=True)
          except Problem.DoesNotExist:
              return self.error("Problem not exist")
          #更新题目提交状态2018.3.14
          submission = CourseSubmission.objects.create(user_id=request.user.id,
                                                 username=request.user.username,
                                                 language=data["language"],
                                                 code=data["code"],
                                                 problem_id=problem.id,
                                                 ip=request.session["ip"])
          # use this for debug
          #CourseJudgeDispatcher(submission.id, problem.id,course_id,task_id).judge()
          judge_course.delay(submission.id, problem.id,course_id,task_id)#2018.2.4
          if hide_id:
              return self.success()
          else:
              return self.success({"submission_id": submission.id})
  
  
  class CourseSubmissionAPI(APIView):
      def get(self, request):
          submission_id = request.GET.get("id")
          if not submission_id:
              return self.error("Parameter id doesn't exist")
          try:
              submission = CourseSubmission.objects.select_related("problem").get(id=submission_id)
          except CourseSubmission.DoesNotExist:
              return self.error("Submission doesn't exist")
  
          if submission.problem.rule_type == ProblemRuleType.OI or request.user.is_admin_role():
              submission_data = CourseSubmissionModelSerializer(submission).data
          else:
              submission_data = CourseSubmissionSafeModelSerializer(submission).data
          # 是否有权限取消共享
          submission_data["can_unshare"] = submission.check_user_permission(request.user, check_share=False)
          return self.success(submission_data)
  