307 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			307 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
| import json
 | ||
| 
 | ||
| from django_filters.rest_framework import DjangoFilterBackend
 | ||
| from openpyxl import Workbook, load_workbook
 | ||
| from rest_framework import status
 | ||
| from rest_framework.decorators import action, permission_classes
 | ||
| from rest_framework.filters import OrderingFilter, SearchFilter
 | ||
| from rest_framework.generics import GenericAPIView
 | ||
| from rest_framework.permissions import IsAdminUser, 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 crm.models import Consumer, PaySubject
 | ||
| from examtest.models import WorkScope
 | ||
| from server import settings
 | ||
| from utils.custom import CommonPagination
 | ||
| from .exports import export_question
 | ||
| 
 | ||
| 
 | ||
| from .models import Question, Questioncat
 | ||
| from .serializers import (QuestioncatSerializer, QuestioncatSerializerDefault,
 | ||
|                           QuestionSerializer, SubjectSerializer)
 | ||
| 
 | ||
| 
 | ||
| class SubjectViewSet(ModelViewSet):
 | ||
|     """
 | ||
|     学科分类:增删改查
 | ||
|     """
 | ||
|     perms_map = (
 | ||
|         {'get': 'subject_view'}, {'post': 'subject_create'},
 | ||
|         {'put': 'subject_update'}, {'delete': 'subject_delete'})
 | ||
|     queryset = Questioncat.objects.filter(is_subject=True,is_delete=0).all().order_by("id")
 | ||
|     serializer_class = SubjectSerializer
 | ||
|     pagination_class = None
 | ||
|     ordering_fields = ('id',)
 | ||
|     ordering = ['id']
 | ||
|     search_fields = ('^name',)
 | ||
|     
 | ||
| 
 | ||
| class QuestioncatViewSet(ModelViewSet):
 | ||
|     """
 | ||
|     题库分类:增删改查
 | ||
|     """
 | ||
|     perms_map = (
 | ||
|         {'get': 'questioncat_view'}, {'post': 'questioncat_create'},
 | ||
|         {'put': 'questioncat_update'}, {'delete': 'questioncat_delete'})
 | ||
|     queryset = Questioncat.objects.filter(is_delete=0,is_subject=False).all()
 | ||
|     serializer_class = QuestioncatSerializerDefault
 | ||
|     pagination_class = CommonPagination
 | ||
|     ordering_fields = ['id']
 | ||
|     ordering = ['type','id']
 | ||
|     filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
 | ||
|     filterset_fields = ['pid']
 | ||
|     search_fields = ['name']
 | ||
| 
 | ||
|     @action(methods=['get'], detail=False,
 | ||
|             url_path='all', url_name='all_questioncat')
 | ||
|     def all(self, request):
 | ||
|         """
 | ||
|         题库分类全,不分页
 | ||
|         """
 | ||
|         queryset = Questioncat.objects.filter(is_delete=0).all()
 | ||
|         if request.query_params.get('pid',None):
 | ||
|             queryset = queryset.filter(pid = request.query_params.get('pid'))
 | ||
|         serializer = QuestioncatSerializer(instance=queryset,many=True)
 | ||
|         return Response(serializer.data)
 | ||
|     
 | ||
|     @action(methods=['get'], detail=False,
 | ||
|             url_path='subject', url_name='questioncat_subject', pagination_class = None, permission_classes=[])
 | ||
|     def subject(self, request):
 | ||
|         """
 | ||
|         学科下的全部分类
 | ||
|         """
 | ||
|         queryset = Questioncat.objects.filter(is_delete=0, pid=request.query_params.get('id')).all()
 | ||
|         serializer = QuestioncatSerializer(instance=queryset,many=True)
 | ||
|         return Response(serializer.data)
 | ||
|     
 | ||
|     @action(methods=['get'], detail=False,
 | ||
|             url_path='workscope', url_name='questioncat_workscope', pagination_class = None, permission_classes=[])
 | ||
|     def workscope(self, request):
 | ||
|         """
 | ||
|         工作类别下的全部分类
 | ||
|         """
 | ||
|         queryset = WorkScope.objects.get(id=request.query_params.get('id')).questioncat.all().order_by('pk')
 | ||
|         serializer = QuestioncatSerializer(instance=queryset,many=True)
 | ||
|         return Response(serializer.data)
 | ||
|     
 | ||
| from django.db.models import Q
 | ||
| class QuestionViewSet(ModelViewSet):
 | ||
|     """
 | ||
|     题目:增删改查
 | ||
|     """
 | ||
|     perms_map = (
 | ||
|         {'get': 'question_view'}, {'post': 'question_create'},
 | ||
|         {'put': 'question_update'}, {'delete': 'question_delete'})
 | ||
|     queryset = Question.objects.filter(is_delete=0).all()
 | ||
|     serializer_class = QuestionSerializer
 | ||
|     pagination_class = CommonPagination
 | ||
|     ordering_fields = ['id', 'name']
 | ||
|     ordering = ['-create_time']
 | ||
|     filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
 | ||
|     filterset_fields = ['questioncat','level', 'type']
 | ||
|     search_fields = ['name', 'options', 'resolution']
 | ||
| 
 | ||
|     @action(methods=['post'], detail=False,
 | ||
|             url_path='count', url_name='question_count')
 | ||
|     def count(self, request):
 | ||
|         ret = {'danxuan':0,'duoxuan':0,'panduan':0}
 | ||
|         queryset = self.queryset
 | ||
|         if request.data.get('ids',None):
 | ||
|             queryset = queryset.filter(questioncat__in = request.data.get('ids'))
 | ||
|             ret['danxuan'] = queryset.filter(type='单选').count()
 | ||
|             ret['duoxuan'] = queryset.filter(type='多选').count()
 | ||
|             ret['panduan'] = queryset.filter(type='判断').count()
 | ||
|         return Response(ret)
 | ||
|     
 | ||
|     def get_queryset(self):
 | ||
|         user = self.request.user
 | ||
|         if isinstance(user, Consumer):
 | ||
|             questioncats = user.workscope.questioncat.all()
 | ||
|             self.queryset = self.queryset.filter(questioncat__in = questioncats)
 | ||
|         return super().get_queryset()
 | ||
| 
 | ||
|     @action(methods=['get'], detail=False,
 | ||
|             url_path='export', url_name='export_question', perms_map=[{'*':'export_question'}])
 | ||
|     def export(self, request):
 | ||
|         queryset = self.filter_queryset(self.get_queryset())
 | ||
|         path = export_question(queryset)
 | ||
|         return Response({'path': path})
 | ||
|     
 | ||
|     @action(methods=['get'], detail=False,
 | ||
|             url_path='correct', url_name='correct_question', permission_classes=[IsAuthenticated])
 | ||
|     def correct(self, request):
 | ||
|         # for i in Question.objects.all():
 | ||
|         #     options = i.options
 | ||
|         #     for k in options:
 | ||
|         #         options[k] = str(options[k]).replace('<p>','').replace('</p>','')\
 | ||
|         #         .replace('×','×').replace('β','β').replace('α','α')\
 | ||
|         #             .replace('γ','γ').replace(' ',' ')
 | ||
|         #     i.options = options
 | ||
|         #     i.save()
 | ||
|         for i in Question.objects.filter(Q(options__A__contains='μ')|Q(options__B__contains='μ')|Q(options__C__contains='μ')|Q(options__D__contains='μ')|Q(options__E__contains='μ')|Q(options__F__contains='μ')):
 | ||
|             print(i)
 | ||
|             options = i.options
 | ||
|             for k in options:
 | ||
|                 options[k] = str(options[k]).replace('μ','μ')
 | ||
|             i.options = options
 | ||
|             i.save()
 | ||
|         return Response()
 | ||
| 
 | ||
|     @action(methods=['post'], detail=False, perms_map=[{'*':'question_delete'}])
 | ||
|     def deletes(self, request):
 | ||
|         """
 | ||
|         批量删除
 | ||
|         """
 | ||
|         ids = request.data.get('ids', [])
 | ||
|         if request.user.is_superuser:
 | ||
|             Question.objects.filter(id__in=ids).update(is_delete=True)
 | ||
|             return Response()
 | ||
|         return Response({'error':'权限不足'})
 | ||
| 
 | ||
|     @action(methods=['post'], detail=False, url_name='enable_question', permission_classes=[IsAuthenticated])
 | ||
|     def enable(self, request):
 | ||
|         ids = request.data.get('ids',None)
 | ||
|         if ids:
 | ||
|             Question.objects.filter(pk__in=ids).update(enabled=True)
 | ||
|             return Response(status=status.HTTP_200_OK)
 | ||
| 
 | ||
|     @action(methods=['post'], detail=False,
 | ||
|             url_path='import', url_name='import_question',perms_map=[{'post':'question_import'}])
 | ||
|     def import_question(self, request):
 | ||
|         """
 | ||
|         导入题目
 | ||
|         """
 | ||
|         xlsxpath = request.data['path']
 | ||
|         fullpath = settings.BASE_DIR + xlsxpath
 | ||
|         wb = load_workbook(fullpath)
 | ||
|         sheet = wb.worksheets[0]
 | ||
|         qlist = ['A','B','C','D','E','F']
 | ||
|         leveldict = {'低':'低','中':'中','高':'高'}
 | ||
|         notinlist = []
 | ||
|         # 验证文件内容
 | ||
|         if sheet['a2'].value != '题目类型':
 | ||
|             return Response({"error":"类型列错误!"})
 | ||
|         if sheet['b2'].value != '分类':
 | ||
|             return Response({"error":"分类列错误!"})
 | ||
|         if sheet['c2'].value != '题目':
 | ||
|             return Response({"error":"题目列错误!"})
 | ||
|         questioncatdict = {}
 | ||
|         questioncats = Questioncat.objects.filter(is_delete=0)
 | ||
|         for i in questioncats:
 | ||
|             questioncatdict[i.name] = i.id
 | ||
|         i = 3
 | ||
|         while sheet['c'+str(i)].value:
 | ||
|             type = sheet['a'+str(i)].value.replace(' ', '')
 | ||
|             questioncat = sheet['b'+str(i)].value.replace(' ', '')
 | ||
|             name = sheet['c'+str(i)].value
 | ||
|             answer = {}
 | ||
|             if sheet['d'+str(i)].value:
 | ||
|                 answer['A'] = sheet['d'+str(i)].value
 | ||
|             if sheet['e'+str(i)].value:
 | ||
|                 answer['B'] = sheet['e'+str(i)].value
 | ||
|             if sheet['f'+str(i)].value:
 | ||
|                 answer['C'] = sheet['f'+str(i)].value
 | ||
|             if sheet['g'+str(i)].value:
 | ||
|                 answer['D'] = sheet['g'+str(i)].value
 | ||
|             if sheet['h'+str(i)].value:
 | ||
|                 answer['E'] = sheet['h'+str(i)].value
 | ||
|             if sheet['i'+str(i)].value:
 | ||
|                 answer['F'] = sheet['i'+str(i)].value
 | ||
|             right = sheet['j'+str(i)].value.replace(' ', '')
 | ||
|             resolution = sheet['k'+str(i)].value
 | ||
|             level = sheet['l'+str(i)].value
 | ||
|             if level:
 | ||
|                 level = level.replace(' ', '')
 | ||
|             if questioncat not in questioncatdict:
 | ||
|                  return Response({"error":"不存在分类("+questioncat+")!请先新建"})
 | ||
|             else:
 | ||
|                 cateobj = Questioncat.objects.get(id=questioncatdict[questioncat])
 | ||
|             if type == '单选':
 | ||
|                 if Question.objects.filter(type='单选',name=name, is_delete=0, questioncat=cateobj).exists():
 | ||
|                     notinlist.append(i)
 | ||
|                 else:
 | ||
|                     if right in ['A','B','C','D','E','F']:        
 | ||
|                         obj = Question()
 | ||
|                         obj.type = '单选'
 | ||
|                         obj.questioncat = cateobj
 | ||
|                         obj.name = name
 | ||
|                         obj.options=answer
 | ||
|                         obj.right = right
 | ||
|                         obj.resolution = resolution if resolution else ''
 | ||
|                         if level in leveldict:
 | ||
|                             obj.level = leveldict[level]
 | ||
|                         else:
 | ||
|                             obj.level = '低'
 | ||
|                         obj.save()
 | ||
|             elif type == '多选':
 | ||
|                 right = list(right)
 | ||
|                 if Question.objects.filter(type='多选', name=name, is_delete=0, questioncat=cateobj).exists():
 | ||
|                     notinlist.append(i)
 | ||
|                 else:
 | ||
|                     if [False for c in right if c not in qlist]:
 | ||
|                         pass
 | ||
|                     else:
 | ||
|                         obj = Question()
 | ||
|                         obj.type = '多选'
 | ||
|                         obj.questioncat = cateobj
 | ||
|                         obj.name = name
 | ||
|                         obj.options=answer
 | ||
|                         obj.right = right
 | ||
|                         obj.resolution = resolution if resolution else ''
 | ||
|                         if level in leveldict:
 | ||
|                             obj.level = leveldict[level]
 | ||
|                         else:
 | ||
|                             obj.level = '低'
 | ||
|                         obj.save()
 | ||
|             elif type == '判断':
 | ||
|                 if right == 'A' or right == '对' or right == '正确':
 | ||
|                     right = 'A'
 | ||
|                 else:
 | ||
|                     right = 'B'
 | ||
|                 if Question.objects.filter(type='判断',name=name, is_delete=0, questioncat=cateobj).exists():
 | ||
|                     notinlist.append(i)
 | ||
|                 else:
 | ||
|                     obj = Question()
 | ||
|                     obj.type = '判断'
 | ||
|                     obj.questioncat = cateobj
 | ||
|                     obj.name = name
 | ||
|                     obj.options={'A':'对','B':'错'}
 | ||
|                     obj.right = right
 | ||
|                     obj.resolution = resolution if resolution else ''
 | ||
|                     if level in leveldict:
 | ||
|                         obj.level = leveldict[level]
 | ||
|                     else:
 | ||
|                         obj.level = '低'
 | ||
|                     obj.save()
 | ||
|             i = i +1
 | ||
|         return Response(status=status.HTTP_200_OK)
 | ||
| 
 | ||
| class ExerciseView(APIView):
 | ||
|     perms_map=[{'post':'exercise'}]
 | ||
|     def post(self, request):
 | ||
|         questioncat = request.data['questioncat']
 | ||
|         queryset = Question.objects.filter(is_delete=0,questioncat=questioncat,enabled=True).order_by('type','pk', 'name')
 | ||
|         if 'ydtms' in request.data and request.data['ydtms']:
 | ||
|             queryset = queryset.exclude(id__in = request.data['ydtms'])
 | ||
|         if 'ydtms_' in request.data and request.data['ydtms_']:
 | ||
|             consumer = request.user
 | ||
|             process = consumer.process
 | ||
|             process['cat'+str(questioncat)] = request.data['ydtms_']
 | ||
|             consumer.process = process
 | ||
|             consumer.save()
 | ||
|         count = queryset.count()
 | ||
|         pg = CommonPagination()
 | ||
|         p = pg.paginate_queryset(queryset=queryset,request=request,view=self)
 | ||
|         serializer = QuestionSerializer(instance=p,many=True)
 | ||
|         collects = request.user.collects.all().values_list('id',flat=True) #当前用户收藏的题目
 | ||
|         results = serializer.data
 | ||
|         for i in results:
 | ||
|             if i['id'] in collects:
 | ||
|                 i['is_collect'] = True
 | ||
|             else:
 | ||
|                 i['is_collect'] = False
 | ||
|         return Response({'count':count, 'results':results})
 |