191 lines
7.8 KiB
Python
191 lines
7.8 KiB
Python
|
||
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, 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_update'},
|
||
{'put': 'threshold_update'}, {'delete': 'threshold_update'}]
|
||
queryset = Source.objects.filter(is_delete=0)
|
||
pagination_class = CommonPagination
|
||
filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
|
||
serializer_class = SourceSerializer
|
||
search_fields = ['name','author']
|
||
filterset_fields = ['name', 'author', 'publish_year']
|
||
|
||
|
||
class ThresholdViewSet(ModelViewSet):
|
||
perms_map = [
|
||
{'get': 'threshold_view'}, {'post': 'threshold_update'},
|
||
{'put': 'threshold_update'}, {'delete': 'threshold_update'}]
|
||
queryset = Threshold.objects.filter(is_delete=0)
|
||
serializer_class = ThresholdSerializer
|
||
pagination_class = CommonPagination
|
||
filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
|
||
search_fields = ['chinese_name','cas', 'compound_cate', 'odor_type']
|
||
filterset_fields = ['source', 'compound_cate']
|
||
|
||
@action(methods=['post'], detail=False, perms_map=[{'post':'threshold_update'}], serializer_class=PathSerializer)
|
||
@transaction.atomic
|
||
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()
|
||
|
||
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.get_or_create(defaults=item, name=item['name'])
|
||
sources_dict[str(source_sheet[f'a{i}'].value)] = source
|
||
i = i + 1
|
||
# self.handle_other_sheet(wb, '醇类', sources_dict)
|
||
# self.handle_other_sheet(wb, '醛类', sources_dict)
|
||
# self.handle_other_sheet(wb, '酸类', sources_dict)
|
||
# self.handle_other_sheet(wb, '酯类', sources_dict)
|
||
# self.handle_other_sheet(wb, '酮类', sources_dict)
|
||
# self.handle_other_sheet(wb, '醚类', sources_dict)
|
||
# self.handle_other_sheet(wb, '酚类', sources_dict)
|
||
# self.handle_other_sheet(wb, '苯系物', sources_dict)
|
||
# self.handle_other_sheet(wb, '卤代烃', sources_dict)
|
||
self.handle_other_sheet(wb, '烷烃类', sources_dict)
|
||
self.handle_other_sheet(wb, '烯烃类', sources_dict)
|
||
self.handle_other_sheet(wb, '硫化物', sources_dict)
|
||
self.handle_other_sheet(wb, '胺类', sources_dict)
|
||
self.handle_other_sheet(wb, '其他', sources_dict)
|
||
|
||
def handle_other_sheet(self, wb: Workbook, name, sources_dict):
|
||
sheet = wb.get_sheet_by_name(name)
|
||
i = 2
|
||
early_name = ''
|
||
early_cas = ''
|
||
while sheet[f'b{i}'].value:
|
||
item = {}
|
||
chinese_name = sheet[f'a{i}'].value
|
||
if chinese_name:
|
||
early_name = chinese_name
|
||
else:
|
||
chinese_name = early_name
|
||
item['chinese_name'] = chinese_name
|
||
ppm = sheet[f'b{i}'].value
|
||
if isinstance(ppm, str):
|
||
if '<' in ppm or '<' in ppm:
|
||
item['ppm_sign'] = '<'
|
||
elif '>' in ppm or '>'in ppm:
|
||
item['ppm_sign'] = '>'
|
||
ppm = float(ppm.replace('>', '').replace('<', '').replace('>', '').replace('<', ''))
|
||
item['ppm'] = ppm
|
||
mass = sheet[f'c{i}'].value
|
||
if isinstance(mass, str):
|
||
if '<' in mass or '<' in mass:
|
||
item['mass_sign'] = '<'
|
||
elif '>' in mass or '>'in mass:
|
||
item['mass_sign'] = '>'
|
||
mass = float(mass.replace('>', '').replace('<', '').replace('>', '').replace('<', ''))
|
||
item['mass'] = mass
|
||
item['molecular'] = sheet[f'd{i}'].value
|
||
cas = sheet[f'e{i}'].value
|
||
if cas:
|
||
early_cas = cas
|
||
else:
|
||
cas = early_cas
|
||
item['cas'] = cas
|
||
item['odor_type'] = sheet[f'f{i}'].value
|
||
item['threshold_type'] = sheet[f'g{i}'].value
|
||
item['source'] = sources_dict[str(sheet[f'h{i}'].value)]
|
||
item['compound_cate'] = name
|
||
Threshold.objects.get_or_create(defaults=item,
|
||
chinese_name=chinese_name,
|
||
ppm=ppm, mass=mass)
|
||
i = i + 1
|