172 lines
7.3 KiB
Python
172 lines
7.3 KiB
Python
from rest_framework.filters import SearchFilter, OrderingFilter
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.views import APIView
|
|
from rest_framework.viewsets import ModelViewSet
|
|
from rest_framework.generics import GenericAPIView
|
|
from rest_framework.response import Response
|
|
from rest_framework.decorators import action
|
|
from rest_framework import status
|
|
from django_filters.rest_framework import DjangoFilterBackend
|
|
from openpyxl import Workbook, load_workbook
|
|
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
|
|
from datetime import datetime
|
|
from django.db.models import Avg
|
|
|
|
from utils.custom import CommonPagination
|
|
from rbac.permission import RbacPermission
|
|
from question.models import Question
|
|
from question.serializers import QuestionSerializer
|
|
from .models import TestRule, ExamTest, AnswerDetail
|
|
from .serializers import TestRuleSerializer, TestRuleListSerializer, MoniTestSerializer, AnswerDetailSerializer, ExamTestListSerializer, AnswerDetailCreateSerializer
|
|
from server import settings
|
|
from crm.authentication import ConsumerTokenAuthentication
|
|
from utils.custom import CommonPagination
|
|
|
|
# Create your views here.
|
|
|
|
class MoniTestView(APIView):
|
|
authentication_classes = [ConsumerTokenAuthentication]
|
|
permission_classes = []
|
|
def post(self, request, *args, **kwargs):
|
|
serializer = MoniTestSerializer(data = request.data)
|
|
if serializer.is_valid():
|
|
instance = serializer.save(consumer = request.user)
|
|
if 'questions' in request.data:
|
|
questions = []
|
|
for i in request.data['questions']:
|
|
question = {}
|
|
question['question'] = i['id']
|
|
question['examtest'] = instance.id
|
|
question['score'] = i['score']
|
|
if 'user_answer' in i:
|
|
question['user_answer'] = i['user_answer']
|
|
question['is_right'] = i['is_right']
|
|
questions.append(question)
|
|
serializer_detail = AnswerDetailCreateSerializer(data=questions, many=True)
|
|
if serializer_detail.is_valid():
|
|
serializer_detail.save()
|
|
return Response(MoniTestSerializer(instance).data,status=status.HTTP_200_OK)
|
|
else:
|
|
return Response(serializer_detail.errors)
|
|
|
|
else:
|
|
return Response({'error':'答题记录不存在'})
|
|
else:
|
|
return Response(serializer.errors)
|
|
|
|
|
|
class MyExamTestView(APIView):
|
|
authentication_classes = [ConsumerTokenAuthentication]
|
|
permission_classes = []
|
|
def get(self, request, *args, **kwargs):
|
|
queryset = ExamTest.objects.filter(consumer=request.user)
|
|
pg = CommonPagination()
|
|
p = pg.paginate_queryset(queryset=queryset,request=request,view=self)
|
|
serializer = ExamTestListSerializer(instance=p,many=True)
|
|
return pg.get_paginated_response(serializer.data)
|
|
|
|
class MyExamTestFxView(APIView):
|
|
authentication_classes = [ConsumerTokenAuthentication]
|
|
permission_classes = []
|
|
def get(self, request, *args, **kwargs):
|
|
queryset = ExamTest.objects.filter(consumer=request.user)
|
|
ret = {}
|
|
ret['total'] = queryset.count()
|
|
ret['avg_score'] = queryset.aggregate(avg=Avg('score'))['avg']
|
|
ret['pass_rate'] = round(((queryset.filter(is_pass=True).count())/ret['total'])*100) if ret['total'] else 0
|
|
return Response(ret)
|
|
|
|
class AnswerDetailView(APIView):
|
|
authentication_classes = []
|
|
permission_classes = []
|
|
def get(self, request, *args, **kwargs):
|
|
queryset = AnswerDetail.objects.all()
|
|
if request.query_params.get('examtest', None):
|
|
queryset = queryset.filter(examtest=request.query_params.get('examtest'))
|
|
serializer = AnswerDetailSerializer(instance=queryset,many=True)
|
|
return Response(serializer.data)
|
|
|
|
|
|
class TestRuleViewSet(ModelViewSet):
|
|
"""
|
|
模考规则:增删改查
|
|
"""
|
|
perms_map = (
|
|
{'*': 'admin'}, {'*': 'TestRule_all'}, {'get': 'TestRule_list'}, {'post': 'TestRule_create'},
|
|
{'put': 'TestRule_update'}, {'delete': 'TestRule_delete'})
|
|
pagination_class = None
|
|
queryset = TestRule.objects.filter(is_delete=0).all().order_by("id")
|
|
serializer_class = TestRuleSerializer
|
|
ordering_fields = ('id',)
|
|
ordering = ['id']
|
|
search_fields = ('^name',)
|
|
|
|
def get_serializer(self, *args, **kwargs):
|
|
"""
|
|
Return the serializer instance that should be used for validating and
|
|
deserializing input, and for serializing output.
|
|
"""
|
|
if self.action == 'list':
|
|
serializer_class = TestRuleListSerializer
|
|
else:
|
|
serializer_class = TestRuleSerializer
|
|
kwargs['context'] = self.get_serializer_context()
|
|
return serializer_class(*args, **kwargs)
|
|
|
|
def get_authenticators(self):
|
|
"""
|
|
GET请求不做登陆验证
|
|
"""
|
|
if self.request.method == 'GET':
|
|
self.authentication_classes = []
|
|
return [auth() for auth in self.authentication_classes]
|
|
|
|
def get_permissions(self):
|
|
"""
|
|
GET请求不做权限验证
|
|
"""
|
|
if self.request.method == 'GET':
|
|
self.permission_classes = []
|
|
return [permission() for permission in self.permission_classes]
|
|
|
|
@action(methods=['get'], detail=True, permission_classes=[IsAuthenticated],
|
|
url_path='monitest', url_name='gen_monitest')
|
|
def monitest(self, request, pk=None):
|
|
'''
|
|
生成自助模拟考试
|
|
'''
|
|
ret = {}
|
|
testrule = self.get_object()
|
|
ret['name'] = '自助模考' + datetime.now().strftime('%Y%m%d%H%M')
|
|
ret['type'] = '自助模考' # 自助模拟考试
|
|
ret['rule'] = testrule.id
|
|
ret['limit'] = testrule.limit
|
|
ret['total_score'] = testrule.total_score
|
|
ret['pass_score'] = testrule.pass_score
|
|
ret['danxuan_count'] = testrule.danxuan_count
|
|
ret['danxuan_score'] = testrule.danxuan_score
|
|
ret['duoxuan_count'] = testrule.duoxuan_count
|
|
ret['duoxuan_score'] = testrule.duoxuan_score
|
|
ret['panduan_count'] = testrule.panduan_count
|
|
ret['panduan_score'] = testrule.panduan_score
|
|
question_queryset = Question.objects.none()
|
|
queryset = Question.objects.filter(is_delete=0,questioncat__in = testrule.questioncat.all())
|
|
if ret['danxuan_count']:
|
|
danxuan = queryset.filter(type='单选').order_by('?')[:ret['danxuan_count']]
|
|
question_queryset = question_queryset | danxuan
|
|
if ret['duoxuan_count']:
|
|
duoxuan = queryset.filter(type='多选').order_by('?')[:ret['duoxuan_count']]
|
|
question_queryset = question_queryset | duoxuan
|
|
if ret['panduan_count']:
|
|
panduan = queryset.filter(type='判断').order_by('?')[:ret['panduan_count']]
|
|
question_queryset = question_queryset | panduan
|
|
questions = QuestionSerializer(instance=question_queryset.order_by('type'),many=True).data
|
|
for i in questions:
|
|
if i['type'] == 1:
|
|
i['total_score'] = ret['danxuan_score']
|
|
elif i['type'] == 2:
|
|
i['total_score'] = ret['duoxuan_score']
|
|
else:
|
|
i['total_score'] = ret['panduan_score']
|
|
ret['questions'] = questions
|
|
return Response(ret) |