examtest/test_server/examtest/views.py

296 lines
12 KiB
Python

from datetime import datetime
from django.db.models import Avg
from django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.generics import GenericAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from question.models import Question
from question.serializers import QuestionSerializer
from server import settings
from utils.custom import CommonPagination
from .models import AnswerDetail, Banner, ExamTest
from .models_paper import Paper, PaperQuestions, TestRule, WorkScope
from .serializers import (
AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer,
ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer,
PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer,
WorkScopeSerializer)
# Create your views here.
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 WorkScopeViewSet(ModelViewSet):
"""
工作类别:增删改查
"""
perms_map = [
{'get': 'workscope_list'}, {'post': 'workscope_create'},
{'put': 'workscope_update'}, {'delete': 'workscope_delete'}]
pagination_class = None
queryset = WorkScope.objects.filter(is_delete=0).all().order_by("id")
serializer_class = WorkScopeSerializer
ordering_fields = ('id',)
ordering = ['id']
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['subject']
search_fields = ('^name',)
@action(methods=['get'], detail=True,url_path='monitest', url_name='gen_monitest', perms_map=[{'get':'gen_monitest'}])
def monitest(self, request, pk=None):
'''
生成自助模拟考试
'''
ret = {}
workscope = self.get_object()
ret['name'] = '自助模考' + datetime.now().strftime('%Y%m%d%H%M')
ret['type'] = '自助模考' # 自助模拟考试
ret['workscope'] = workscope.id
ret['limit'] = workscope.rule.limit
ret['total_score'] = workscope.rule.total_score
ret['pass_score'] = workscope.rule.pass_score
ret['danxuan_count'] = workscope.rule.danxuan_count
ret['danxuan_score'] = workscope.rule.danxuan_score
ret['duoxuan_count'] = workscope.rule.duoxuan_count
ret['duoxuan_score'] = workscope.rule.duoxuan_score
ret['panduan_count'] = workscope.rule.panduan_count
ret['panduan_score'] = workscope.rule.panduan_score
question_queryset = Question.objects.none()
queryset = Question.objects.filter(is_delete=0,questioncat__in = workscope.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'] == '单选':
i['total_score'] = ret['danxuan_score']
elif i['type'] == '多选':
i['total_score'] = ret['duoxuan_score']
else:
i['total_score'] = ret['panduan_score']
ret['questions'] = questions
return Response(ret)
class BannerViewSet(ModelViewSet):
"""
轮播图:增删改查
"""
perms_map = (
{'get': 'banner_list'}, {'post': 'banner_create'},
{'put': 'banner_update'}, {'delete': 'banner_delete'})
pagination_class = None
queryset = Banner.objects.filter(is_delete=0).all().order_by("sort")
serializer_class = BannerSerializer
ordering_fields = ('id', 'sort')
ordering = ['sort']
def get_authenticators(self):
if self.request.method == 'GET':
self.authentication_classes = []
return [auth() for auth in self.authentication_classes]
def get_permissions(self):
if self.request.method == 'GET':
self.permission_classes = []
return [permission() for permission in self.permission_classes]
class TestRuleViewSet(ModelViewSet):
"""
模考规则:增删改查
"""
perms_map = (
{'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_authenticators(self):
if self.request.method == 'GET':
self.authentication_classes = []
return [auth() for auth in self.authentication_classes]
def get_permissions(self):
if self.request.method == 'GET':
self.permission_classes = []
return [permission() for permission in self.permission_classes]
class ExamTestViewSet(ModelViewSet):
"""
考试记录列表和详情
"""
perms_map = [{'get': 'examtest_list'},{'post': 'examtest_create'}]
pagination_class = CommonPagination
queryset = ExamTest.objects.filter(is_delete=0).all()
serializer_class = ExamTestListSerializer
ordering_fields = ('id','create_time')
ordering = ['-create_time']
search_fields = ('^name',)
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['type','is_pass']
@action(methods=['get'], detail=False,url_path='self', url_name='selftest', perms_map = [{'get':'examtest_selftest'}])
def selftest(self, request, pk=None):
'''
个人考试记录
'''
queryset = ExamTest.objects.filter(consumer=request.user).order_by('-create_time')
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)
@action(methods=['get'], detail=False,url_path='fx', url_name='selffx', perms_map = [{'get':'examtest_selffx'}])
def selffx(self, request, pk=None):
'''
个人考试分析
'''
queryset = ExamTest.objects.filter(consumer=request.user)
ret = {}
ret['total'] = queryset.count()
ret['avg_score'] = round(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)
def create(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 PaperViewSet(ModelViewSet):
"""
押题卷增删改查
"""
perms_map = [
{'get': 'paper_list'}, {'post': 'paper_create'},
{'put': 'paper_update'}, {'delete': 'paper_delete'}]
queryset = Paper.objects.filter(is_delete=0).all().order_by("id")
pagination_class = CommonPagination
serializer_class = PaperSerializer
ordering_fields = ('id',)
ordering = ['id']
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['workscope']
search_fields = ('^name',)
def get_serializer_class(self):
if self.action=='list':
return PaperSerializer
else:
return PaperDetailSerializer
def create(self, request, *args, **kwargs):
data = request.data
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
instance = serializer.save()
if 'questions' in data:
questions = []
for i in data['questions']:
question = {}
question['question'] = i['id']
question['paper'] = instance.id
question['total_score'] = i['total_score']
questions.append(question)
serializer_detail = PaperQuestionsCreateSerializer(data=questions, many=True)
if serializer_detail.is_valid():
serializer_detail.save()
return Response(status=status.HTTP_200_OK)
else:
return Response(serializer_detail.errors)
else:
return Response({'error':'不存在题库'})
def update(self, request, *args, **kwargs):
data = request.data
instance = self.get_object()
serializer = self.get_serializer(instance, data=data)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if 'questions' in data:
questions = []
for i in data['questions']:
question = {}
question['question'] = i['id']
question['paper'] = instance.id
question['total_score'] = i['total_score']
questions.append(question)
serializer_detail = PaperQuestionsCreateSerializer(data=questions, many=True)
if serializer_detail.is_valid():
PaperQuestions.objects.filter(paper=instance).delete()
serializer_detail.save()
return Response(status=status.HTTP_200_OK)
else:
return Response(serializer_detail.errors)
else:
return Response({'error':'不存在题库'})
@action(methods=['get'], detail=True, url_path='monitest', url_name='gen_monitest', perms_map=[{'get':'gen_monitest'}])
def monitest(self, request, pk=None):
'''
生成押卷模拟考试
'''
ret = {}
paper = self.get_object()
serializer = PaperDetailSerializer(instance=paper)
ret = serializer.data
ret['name'] = '押卷模考' + datetime.now().strftime('%Y%m%d%H%M')
ret['type'] = '押卷模考'
ret['paper'] = paper.id
return Response(ret)