feat: 增加阈值数据库功能part1

This commit is contained in:
caoqianming 2023-12-07 16:26:37 +08:00
parent 9cce706104
commit 374cde0dc9
9 changed files with 211 additions and 25 deletions

View File

@ -1,5 +1,3 @@
from django.shortcuts import render
from requests.api import request
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
@ -11,8 +9,7 @@ import pickle
import requests import requests
from lxml import etree from lxml import etree
from django.db.models import Count from django.db.models import Count
from rbac.models import UserProfile from django.db.models.functions import ExtractMonth, ExtractYear
from django.db.models.functions import ExtractMonth, ExtractWeek, ExtractYear
# Create your views here. # Create your views here.
class BasicCount(APIView): class BasicCount(APIView):

View File

@ -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,
},
),
]

View File

@ -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='来源名称'),
),
]

View File

@ -1,6 +1,5 @@
from django.db import models from django.db import models
import django.utils.timezone as timezone from rbac.models import CommonModel
from rbac.models import SoftCommonModel, CommonModel
# Create your models here. # Create your models here.
class Article(CommonModel): class Article(CommonModel):
@ -40,3 +39,27 @@ class Material(CommonModel):
down_count = models.IntegerField('阅读量', default=0) down_count = models.IntegerField('阅读量', default=0)
sort = models.IntegerField('排序码', default=1) 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)

View File

@ -1,5 +1,6 @@
from rest_framework import serializers 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): class ArticelSerializer(serializers.ModelSerializer):
@ -30,3 +31,19 @@ class MaterialSerializer(serializers.ModelSerializer):
else: else:
return '' 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='文件地址')

View File

@ -1,11 +1,13 @@
from django.urls import path,include from django.urls import path,include
from .views import ArticleViewSet, MaterialViewSet from .views import ArticleViewSet, MaterialViewSet, SourceViewSet, ThresholdViewSet
from rest_framework import routers from rest_framework import routers
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register('article', ArticleViewSet, basename="article") router.register('article', ArticleViewSet, basename="article")
router.register('material', MaterialViewSet, basename="material") router.register('material', MaterialViewSet, basename="material")
router.register('source', SourceViewSet, basename='source')
router.register('threshold', ThresholdViewSet, basename='threshold')
urlpatterns = [ urlpatterns = [
path('', include(router.urls)), path('', include(router.urls)),

View File

@ -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 django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook
from rest_framework import status from rest_framework import status
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.authentication import JSONWebTokenAuthentication from rest_framework.exceptions import ParseError
from rest_framework_jwt.serializers import (jwt_encode_handler, from django.conf import settings
jwt_payload_handler) from openpyxl import load_workbook
from rest_framework_jwt.settings import api_settings from django.db import transaction
# Create your views here. # Create your views here.
from .models import Article, Material from .models import Article, Material, Source, Threshold
from .serializers import ArticelSerializer, ArticelListSerializer, MaterialSerializer from .serializers import ArticelSerializer, ArticelListSerializer, MaterialSerializer, SourceSerializer, ThresholdSerializer, PathSerializer
from utils.custom import CommonPagination from utils.custom import CommonPagination
class ArticleViewSet(ModelViewSet): class ArticleViewSet(ModelViewSet):
""" """
@ -79,4 +69,59 @@ class MaterialViewSet(ModelViewSet):
instance = self.get_object() instance = self.get_object()
instance.down_count = instance.down_count + 1 instance.down_count = instance.down_count + 1
instance.save() instance.save()
return Response({'path':instance.path, 'down_count':instance.down_count}) 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)

View File

@ -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'),
),
]

View File

@ -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', '安全帽'