from django_filters.rest_framework import DjangoFilterBackend from rest_framework import status from rest_framework.decorators import action from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from rest_framework.exceptions import ParseError from django.conf import settings from openpyxl import load_workbook from django.db import transaction # Create your views here. from .models import Article, Material, Source, Threshold from .serializers import ArticelSerializer, ArticelListSerializer, MaterialSerializer, SourceSerializer, ThresholdSerializer, PathSerializer from utils.custom import CommonPagination class ArticleViewSet(ModelViewSet): """ 文章:增删改查 """ perms_map = [ {'get': '*'}, {'post': 'article_create'}, {'put': 'article_update'}, {'delete': 'article_delete'}] queryset = Article.objects.filter(is_delete=0).all() serializer_class = ArticelSerializer pagination_class = CommonPagination filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter] search_fields = ['title','content'] ordering_fields = ['title','update_time'] ordering = ['-is_top', '-update_time'] def get_serializer_class(self): if self.action=='list': return ArticelListSerializer else: return ArticelSerializer @action(methods=['put'], detail=True, url_name='top_article', perms_map=[{'*':'top_article'}]) def top(self, request, *args, **kwargs): ''' 置顶文章 ''' instance = self.get_object() instance.is_top = False if instance.is_top else True instance.save() return Response(status=status.HTTP_200_OK) class MaterialViewSet(ModelViewSet): """ 资料:增删改查 """ perms_map = [ {'get': '*'}, {'post': 'material_create'}, {'put': 'material_update'}, {'delete': 'material_delete'}] queryset = Material.objects.filter(is_delete=0) serializer_class = MaterialSerializer pagination_class = CommonPagination filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter] search_fields = ['name','description'] ordering_fields = ['update_time', 'down_count'] ordering = ['sort', '-down_count'] filterset_fields = ['type', 'name', 'cate'] @action(methods=['get'], detail=True, url_name='down_material', perms_map=[{'*':'down_material'}]) def down(self, request, *args, **kwargs): ''' 下载资料 ''' instance = self.get_object() instance.down_count = instance.down_count + 1 instance.save() return Response({'path':instance.path, 'down_count':instance.down_count}) class SourceViewSet(ModelViewSet): perms_map = [ {'get': '*'}, {'post': 'threshold'}, {'put': 'threshold'}, {'delete': 'threshold'}] queryset = Source.objects.filter(is_delete=0) serializer_class = SourceSerializer search_fields = ['name','author'] filterset_fields = ['name', 'author', 'publish_year'] class ThresholdViewSet(ModelViewSet): perms_map = [ {'get': '*'}, {'post': 'threshold'}, {'put': 'threshold'}, {'delete': 'threshold'}] queryset = Threshold.objects.filter(is_delete=0) serializer_class = ThresholdSerializer search_fields = ['chinese_name','cas', 'compound_cate', 'odor_type'] filterset_fields = ['is_perception', 'is_recognition'] @action(methods=['post'], detail=False, perms_map=[{'post':'threshold'}], serializer_class=PathSerializer) def daoru(self, request, *args, **kwargs): '''导入excel 导入excel ''' data = request.data sr = PathSerializer(data=data) sr.is_valid(raise_exception=True) vdata = sr.validated_data self.handle_xlsx(vdata['path']) return Response() @transaction.atomic def handle_xlsx(self, path): full_path = settings.BASE_DIR + path if not path.endswith('.xlsx'): raise ParseError('请提供xlsx格式文件') wb = load_workbook(full_path, data_only=True) source_sheet = wb.get_sheet_by_name('来源表') i = 3 sources_dict = {} while source_sheet[f'c{i}'].value: item = {} item['name'] = source_sheet[f'c{i}'].value item['author'] = source_sheet[f'd{i}'].value try: item['publish_year'] = int(source_sheet[f'e{i}'].value) except BaseException: pass source, is_created = Source.objects.update_or_create(defaults=item, name=item['name']) sources_dict[str(source_sheet[f'a{i}'].value)] = source i = i + 1 print(sources_dict)