diff --git a/test_server/analyse/views.py b/test_server/analyse/views.py index 8885e8e..4600c51 100644 --- a/test_server/analyse/views.py +++ b/test_server/analyse/views.py @@ -1,5 +1,3 @@ -from django.shortcuts import render -from requests.api import request from rest_framework.views import APIView from rest_framework.response import Response @@ -11,8 +9,7 @@ import pickle import requests from lxml import etree from django.db.models import Count -from rbac.models import UserProfile -from django.db.models.functions import ExtractMonth, ExtractWeek, ExtractYear +from django.db.models.functions import ExtractMonth, ExtractYear # Create your views here. class BasicCount(APIView): diff --git a/test_server/cms/migrations/0010_source_threshold.py b/test_server/cms/migrations/0010_source_threshold.py new file mode 100644 index 0000000..bc6931d --- /dev/null +++ b/test_server/cms/migrations/0010_source_threshold.py @@ -0,0 +1,53 @@ +# Generated by Django 3.2.12 on 2023-08-28 08:53 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('cms', '0009_material_cate'), + ] + + operations = [ + migrations.CreateModel( + name='Source', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_delete', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('name', models.CharField(max_length=100, verbose_name='来源名称')), + ('author', models.CharField(blank=True, max_length=100, null=True, verbose_name='作者')), + ('publish_year', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='发表年份')), + ('note', models.TextField(blank=True, null=True, verbose_name='备注')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Threshold', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_delete', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('is_perception', models.BooleanField(blank=True, null=True, verbose_name='是否感知阈值')), + ('is_recognition', models.BooleanField(blank=True, null=True, verbose_name='是否识别阈值')), + ('compound_cate', models.CharField(max_length=10, verbose_name='化合物分类')), + ('odor_type', models.CharField(blank=True, max_length=50, null=True, verbose_name='气味类型')), + ('chinese_name', models.CharField(max_length=20, verbose_name='中文名')), + ('ppm', models.FloatField(verbose_name='ppm值')), + ('ppm_sign', models.CharField(default='=', max_length=10, verbose_name='ppm符号标记')), + ('mass', models.FloatField(verbose_name='质量浓度')), + ('mass_sign', models.CharField(default='=', max_length=10, verbose_name='质量浓度符号标记')), + ('molecular', models.FloatField(verbose_name='分子质量')), + ('cas', models.CharField(max_length=20, verbose_name='cas号')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/test_server/cms/migrations/0011_alter_source_name.py b/test_server/cms/migrations/0011_alter_source_name.py new file mode 100644 index 0000000..1270774 --- /dev/null +++ b/test_server/cms/migrations/0011_alter_source_name.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2023-08-28 10:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cms', '0010_source_threshold'), + ] + + operations = [ + migrations.AlterField( + model_name='source', + name='name', + field=models.CharField(max_length=200, verbose_name='来源名称'), + ), + ] diff --git a/test_server/cms/models.py b/test_server/cms/models.py index 076984c..cd6cbed 100644 --- a/test_server/cms/models.py +++ b/test_server/cms/models.py @@ -1,6 +1,5 @@ from django.db import models -import django.utils.timezone as timezone -from rbac.models import SoftCommonModel, CommonModel +from rbac.models import CommonModel # Create your models here. class Article(CommonModel): @@ -40,3 +39,27 @@ class Material(CommonModel): down_count = models.IntegerField('阅读量', default=0) sort = models.IntegerField('排序码', default=1) + +class Source(CommonModel): + name = models.CharField('来源名称', max_length=200) + author = models.CharField('作者', max_length=100, null=True, blank=True) + publish_year = models.PositiveSmallIntegerField('发表年份', null=True, blank=True) + note = models.TextField('备注', null=True, blank=True) + + +class Threshold(CommonModel): + is_perception = models.BooleanField('是否感知阈值', null=True, blank=True) + is_recognition = models.BooleanField('是否识别阈值', null=True, blank=True) + compound_cate = models.CharField('化合物分类', max_length=10) + odor_type = models.CharField('气味类型', null=True, blank=True, max_length=50) + chinese_name = models.CharField('中文名', max_length=20) + ppm = models.FloatField('ppm值') + ppm_sign = models.CharField('ppm符号标记', max_length=10, default='=') + mass = models.FloatField('质量浓度') + mass_sign = models.CharField('质量浓度符号标记', max_length=10, default='=') + molecular = models.FloatField('分子质量') + cas = models.CharField('cas号', max_length=20) + + + + diff --git a/test_server/cms/serializers.py b/test_server/cms/serializers.py index b95f2e0..d3b72ad 100644 --- a/test_server/cms/serializers.py +++ b/test_server/cms/serializers.py @@ -1,5 +1,6 @@ from rest_framework import serializers -from .models import Article, Material +from .models import Article, Material, Source, Threshold +from utils.constants import EXCLUDE_FIELDS_BASE class ArticelSerializer(serializers.ModelSerializer): @@ -30,3 +31,19 @@ class MaterialSerializer(serializers.ModelSerializer): else: return '' +class SourceSerializer(serializers.ModelSerializer): + class Meta: + model = Source + fields = '__all__' + read_only_fields = EXCLUDE_FIELDS_BASE + + +class ThresholdSerializer(serializers.ModelSerializer): + class Meta: + model = Threshold + fields = '__all__' + read_only_fields = EXCLUDE_FIELDS_BASE + + +class PathSerializer(serializers.Serializer): + path = serializers.CharField(label='文件地址') \ No newline at end of file diff --git a/test_server/cms/urls.py b/test_server/cms/urls.py index c1b7c24..3b0f40b 100644 --- a/test_server/cms/urls.py +++ b/test_server/cms/urls.py @@ -1,11 +1,13 @@ from django.urls import path,include -from .views import ArticleViewSet, MaterialViewSet +from .views import ArticleViewSet, MaterialViewSet, SourceViewSet, ThresholdViewSet from rest_framework import routers router = routers.DefaultRouter() router.register('article', ArticleViewSet, basename="article") router.register('material', MaterialViewSet, basename="material") +router.register('source', SourceViewSet, basename='source') +router.register('threshold', ThresholdViewSet, basename='threshold') urlpatterns = [ path('', include(router.urls)), diff --git a/test_server/cms/views.py b/test_server/cms/views.py index 35ec5e7..d3e6ede 100644 --- a/test_server/cms/views.py +++ b/test_server/cms/views.py @@ -1,28 +1,18 @@ -import json -import random -import warnings -from calendar import timegm -from datetime import datetime -import requests -from django.db.models import Q 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.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 rest_framework_jwt.serializers import (jwt_encode_handler, - jwt_payload_handler) -from rest_framework_jwt.settings import api_settings +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 -from .serializers import ArticelSerializer, ArticelListSerializer, MaterialSerializer +from .models import Article, Material, Source, Threshold +from .serializers import ArticelSerializer, ArticelListSerializer, MaterialSerializer, SourceSerializer, ThresholdSerializer, PathSerializer from utils.custom import CommonPagination class ArticleViewSet(ModelViewSet): """ @@ -79,4 +69,59 @@ class MaterialViewSet(ModelViewSet): instance = self.get_object() instance.down_count = instance.down_count + 1 instance.save() - return Response({'path':instance.path, 'down_count':instance.down_count}) \ No newline at end of file + 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) diff --git a/test_server/rbac/migrations/0007_alter_userprofile_first_name.py b/test_server/rbac/migrations/0007_alter_userprofile_first_name.py new file mode 100644 index 0000000..c808f9a --- /dev/null +++ b/test_server/rbac/migrations/0007_alter_userprofile_first_name.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2023-08-28 10:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rbac', '0006_userprofile_mpopenid'), + ] + + operations = [ + migrations.AlterField( + model_name='userprofile', + name='first_name', + field=models.CharField(blank=True, max_length=150, verbose_name='first name'), + ), + ] diff --git a/test_server/utils/constants.py b/test_server/utils/constants.py new file mode 100644 index 0000000..0319da4 --- /dev/null +++ b/test_server/utils/constants.py @@ -0,0 +1,13 @@ +from django.db import models + +EXCLUDE_FIELDS_BASE = ['create_time', 'update_time', 'is_delete'] +EXCLUDE_FIELDS = ['create_time', 'update_time', 'is_delete', 'create_by', 'update_by'] + + +class ObjCate(models.IntegerChoices): + EMPLOYEE = 10, '个人' + POST = 20, '岗位' + + +class Algo(models.TextChoices): + HELMET = 'helmet', '安全帽'