Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
d400f53905
|
@ -61,9 +61,9 @@ class FIFO(CommonAModel):
|
|||
operator = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE)
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True)
|
||||
|
||||
class FIFODetail(CommonAModel):
|
||||
"""
|
||||
领料详细记录
|
||||
"""
|
||||
|
||||
# class FIFODetail(CommonAModel):
|
||||
# """
|
||||
# 领料详细记录
|
||||
# """
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.6 on 2021-10-21 08:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mtm', '0024_alter_recordformfield_rule_expression'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='outputmaterial',
|
||||
name='is_main',
|
||||
field=models.BooleanField(default=True, verbose_name='是否主产出'),
|
||||
),
|
||||
]
|
|
@ -177,6 +177,7 @@ class OutputMaterial(CommonAModel):
|
|||
输出物料
|
||||
"""
|
||||
material = models.ForeignKey(Material, verbose_name='输出物料', on_delete=models.CASCADE, related_name='outputmaterial')
|
||||
is_main = models.BooleanField('是否主产出', default=True) # 以该产品完成度计算进度
|
||||
count = models.FloatField('产出量', default=1)
|
||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||
sort = models.IntegerField('排序号', default=1)
|
||||
|
|
|
@ -98,9 +98,11 @@ class InputMaterialUpdateSerializer(serializers.ModelSerializer):
|
|||
class OutputMaterialSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = OutputMaterial
|
||||
fields = ['count', 'sort', 'material', 'subproduction']
|
||||
fields = ['count', 'sort', 'material', 'subproduction', 'is_main']
|
||||
|
||||
def create(self, validated_data):
|
||||
if OutputMaterial.objects.filter(subproduction=validated_data['subproduction'], is_deleted=False, is_main=True).exists():
|
||||
raise ValidationError('主产出只能有1个')
|
||||
if OutputMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False).exists():
|
||||
raise ValidationError('该物料已存在')
|
||||
return super().create(validated_data)
|
||||
|
@ -108,7 +110,7 @@ class OutputMaterialSerializer(serializers.ModelSerializer):
|
|||
class OutputMaterialUpdateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = OutputMaterial
|
||||
fields = ['count', 'sort']
|
||||
fields = ['count', 'sort', 'is_main']
|
||||
|
||||
class UsedStepCreateSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
|
|
|
@ -17,6 +17,8 @@ class TicketFilterSet(filters.FilterSet):
|
|||
queryset = queryset.filter(participant__contains=user.id).exclude(act_state__in=[Ticket.TICKET_ACT_STATE_FINISH, Ticket.TICKET_ACT_STATE_CLOSED])
|
||||
elif value == 'worked':
|
||||
queryset = queryset.filter(ticketflow_ticket__participant=user).exclude(create_by=user).order_by('-update_time').distinct()
|
||||
elif value == 'cc':
|
||||
pass
|
||||
elif value == 'all':
|
||||
pass
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# Generated by Django 3.2.6 on 2021-10-21 02:49
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('system', '0003_auto_20210812_0909'),
|
||||
('wf', '0014_wfscript'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='state',
|
||||
name='filter_policy',
|
||||
field=models.IntegerField(choices=[(0, '无'), (1, '和工单同属一及上级部门'), (2, '和创建人同属一及上级部门'), (3, '和上步处理人同属一及上级部门')], default=0, verbose_name='参与人过滤策略'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='belong_dept',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ticket_belong_dept', to='system.organization', verbose_name='所属部门'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='state',
|
||||
name='participant_type',
|
||||
field=models.IntegerField(blank=True, choices=[(0, '无处理人'), (1, '个人'), (2, '多人'), (3, '部门'), (4, '角色'), (5, '变量'), (6, '脚本'), (7, '工单的字段'), (8, '父工单的字段'), (9, '代码获取')], default=1, help_text='0.无处理人,1.个人,2.多人,3.部门,4.角色,5.变量(支持工单创建人,创建人的leader),6.脚本,7.工单的字段内容(如表单中的"测试负责人",需要为用户名或者逗号隔开的多个用户名),8.父工单的字段内容。 初始状态请选择类型5,参与人填create_by', verbose_name='参与者类型'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ticket',
|
||||
name='participant_type',
|
||||
field=models.IntegerField(choices=[(0, '无处理人'), (1, '个人'), (2, '多人'), (3, '部门'), (4, '角色'), (5, '变量'), (6, '脚本'), (7, '工单的字段'), (8, '父工单的字段'), (9, '代码获取')], default=0, help_text='0.无处理人,1.个人,2.多人', verbose_name='当前处理人类型'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ticketflow',
|
||||
name='participant_type',
|
||||
field=models.IntegerField(choices=[(0, '无处理人'), (1, '个人'), (2, '多人'), (3, '部门'), (4, '角色'), (5, '变量'), (6, '脚本'), (7, '工单的字段'), (8, '父工单的字段'), (9, '代码获取')], default=0, help_text='0.无处理人,1.个人,2.多人', verbose_name='处理人类型'),
|
||||
),
|
||||
]
|
|
@ -1,3 +1,4 @@
|
|||
from random import choice
|
||||
from django.db import models
|
||||
from django.db.models.base import Model
|
||||
import django.utils.timezone as timezone
|
||||
|
@ -39,16 +40,18 @@ class State(CommonAModel):
|
|||
PARTICIPANT_TYPE_ROBOT = 6
|
||||
PARTICIPANT_TYPE_FIELD = 7
|
||||
PARTICIPANT_TYPE_PARENT_FIELD = 8
|
||||
PARTICIPANT_TYPE_FORMCODE = 9
|
||||
state_participanttype_choices = (
|
||||
(0, '无处理人'),
|
||||
(PARTICIPANT_TYPE_PERSONAL, '个人'),
|
||||
(PARTICIPANT_TYPE_MULTI, '多人'),
|
||||
(PARTICIPANT_TYPE_DEPT, '部门'),
|
||||
# (PARTICIPANT_TYPE_DEPT, '部门'),
|
||||
(PARTICIPANT_TYPE_ROLE, '角色'),
|
||||
(PARTICIPANT_TYPE_VARIABLE, '变量'),
|
||||
# (PARTICIPANT_TYPE_VARIABLE, '变量'),
|
||||
(PARTICIPANT_TYPE_ROBOT, '脚本'),
|
||||
(PARTICIPANT_TYPE_FIELD, '工单的字段'),
|
||||
(PARTICIPANT_TYPE_PARENT_FIELD, '父工单的字段')
|
||||
# (PARTICIPANT_TYPE_PARENT_FIELD, '父工单的字段'),
|
||||
(PARTICIPANT_TYPE_FORMCODE, '代码获取')
|
||||
)
|
||||
STATE_DISTRIBUTE_TYPE_ACTIVE = 1 # 主动接单
|
||||
STATE_DISTRIBUTE_TYPE_DIRECT = 2 # 直接处理(当前为多人的情况,都可以处理,而不需要先接单)
|
||||
|
@ -64,6 +67,13 @@ class State(CommonAModel):
|
|||
STATE_FIELD_READONLY= 1 # 字段只读
|
||||
STATE_FIELD_REQUIRED = 2 # 字段必填
|
||||
STATE_FIELD_OPTIONAL = 3 # 字段可选
|
||||
|
||||
state_filter_choices=(
|
||||
(0, '无'),
|
||||
(1, '和工单同属一及上级部门'),
|
||||
(2, '和创建人同属一及上级部门'),
|
||||
(3, '和上步处理人同属一及上级部门'),
|
||||
)
|
||||
name = models.CharField('名称', max_length=50)
|
||||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||||
is_hidden = models.BooleanField('是否隐藏', default=False, help_text='设置为True时,获取工单步骤api中不显示此状态(当前处于此状态时除外)')
|
||||
|
@ -74,6 +84,7 @@ class State(CommonAModel):
|
|||
participant = models.JSONField('参与者', default=list, blank=True, help_text='可以为空(无处理人的情况,如结束状态)、userid、userid列表\部门id\角色id\变量(create_by,create_by_tl)\脚本记录的id等,包含子工作流的需要设置处理人为loonrobot')
|
||||
state_fields = models.JSONField('表单字段', default=dict, help_text='json格式字典存储,包括读写属性1:只读,2:必填,3:可选. 示例:{"create_time":1,"title":2, "sn":1}, 内置特殊字段participant_info.participant_name:当前处理人信息(部门名称、角色名称),state.state_name:当前状态的状态名,workflow.workflow_name:工作流名称') # json格式存储,包括读写属性1:只读,2:必填,3:可选,4:不显示, 字典的字典
|
||||
distribute_type = models.IntegerField('分配方式', default=1, choices=state_distribute_choices, help_text='1.主动接单(如果当前处理人实际为多人的时候,需要先接单才能处理) 2.直接处理(即使当前处理人实际为多人,也可以直接处理) 3.随机分配(如果实际为多人,则系统会随机分配给其中一个人) 4.全部处理(要求所有参与人都要处理一遍,才能进入下一步)')
|
||||
filter_policy = models.IntegerField('参与人过滤策略', default=0, choices=state_filter_choices)
|
||||
|
||||
class Transition(CommonAModel):
|
||||
"""
|
||||
|
@ -155,7 +166,7 @@ class CustomField(CommonAModel):
|
|||
help_text='radio,checkbox,select,multiselect类型可供选择的选项,格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
|
||||
label = models.JSONField('标签', blank=True, default=dict, help_text='自定义标签,json格式,调用方可根据标签自行处理特殊场景逻辑,loonflow只保存文本内容')
|
||||
|
||||
class Ticket(CommonAModel):
|
||||
class Ticket(CommonBModel):
|
||||
"""
|
||||
工单
|
||||
"""
|
||||
|
@ -177,9 +188,9 @@ class Ticket(CommonAModel):
|
|||
category_choices =(
|
||||
('all', '全部'),
|
||||
('owner', '我创建的'),
|
||||
('duty', '代办'),
|
||||
('duty', '待办'),
|
||||
('worked', '我处理的'),
|
||||
('relation', '抄送我的')
|
||||
('cc', '抄送我的')
|
||||
)
|
||||
title = models.CharField('标题', max_length=500, blank=True, default='', help_text="工单标题")
|
||||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='关联工作流')
|
||||
|
@ -209,7 +220,6 @@ class TicketFlow(BaseModel):
|
|||
ticket_data = models.JSONField('工单数据', default=dict, blank=True, help_text='可以用于记录当前表单数据,json格式')
|
||||
intervene_type = models.IntegerField('干预类型', default=0, help_text='流转类型', choices=Transition.intervene_type_choices)
|
||||
|
||||
|
||||
class WfScript(CommonAModel):
|
||||
"""
|
||||
执行脚本
|
||||
|
@ -222,5 +232,6 @@ class WfScript(CommonAModel):
|
|||
wait = models.BooleanField('是否等待执行完成', default=True)
|
||||
name = models.CharField('脚本名称', max_length=100)
|
||||
workflow = models.ForeignKey(Workflow, verbose_name='关联工作流', null=True, blank=True, on_delete=models.SET_NULL)
|
||||
func_str = models.CharField('函数名', max_length=50, null=True, blank=True)
|
||||
content = models.TextField('脚本内容')
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
class GetParticipants:
|
||||
|
||||
all_funcs = [
|
||||
{'func':'get_create_by', 'name':'获取工单创建人'}
|
||||
]
|
||||
|
||||
# def all_funcs(self):
|
||||
# # return list(filter(lambda x: x.startswith('get_') and callable(getattr(self, x)), dir(self)))
|
||||
# return [(func, getattr(self, func).__doc__) for func in dir(self) if callable(getattr(self, func)) and func.startswith('get_')]
|
||||
|
||||
def get_create_by(self, state:dict={}, ticket:dict={}, ticket_data:dict={}, request={}):
|
||||
"""工单创建人"""
|
||||
participant = ticket.create_by.id
|
||||
return participant
|
|
@ -7,6 +7,7 @@ from rest_framework.exceptions import APIException
|
|||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
import random
|
||||
from .scripts import GetParticipants
|
||||
|
||||
class WfService(object):
|
||||
@staticmethod
|
||||
|
@ -104,7 +105,7 @@ class WfService(object):
|
|||
|
||||
|
||||
@classmethod
|
||||
def get_next_state_by_transition_and_ticket_info(cls, ticket:Ticket, transition: Transition, ticket_data:dict={})->object:
|
||||
def get_next_state_by_transition_and_ticket_info(cls, ticket:Ticket, transition: Transition, ticket_data:dict={}, request:dict={})->object:
|
||||
"""
|
||||
获取下个节点状态
|
||||
"""
|
||||
|
@ -119,12 +120,12 @@ class WfService(object):
|
|||
for i in transition.condition_expression:
|
||||
expression = i['expression'].format(**ticket_all_value)
|
||||
import datetime, time # 用于支持条件表达式中对时间的操作
|
||||
if eval(expression):
|
||||
if eval(expression, {"__builtins__":None}, {'datetime':datetime, 'time':time}):
|
||||
destination_state = State.objects.get(pk=i['target_state'])
|
||||
return destination_state
|
||||
|
||||
@classmethod
|
||||
def get_ticket_state_participant_info(cls, state:State, ticket:Ticket, ticket_data:dict={}):
|
||||
def get_ticket_state_participant_info(cls, state:State, ticket:Ticket, ticket_data:dict={}, request={}):
|
||||
"""
|
||||
获取工单目标状态实际的处理人, 处理人类型
|
||||
"""
|
||||
|
@ -147,15 +148,29 @@ class WfService(object):
|
|||
if destination_participant_type == State.PARTICIPANT_TYPE_FIELD:
|
||||
destination_participant = ticket_data.get(destination_participant, 0) if destination_participant in ticket_data \
|
||||
else Ticket.ticket_data.get(destination_participant, 0)
|
||||
elif destination_participant_type == State.PARTICIPANT_TYPE_DEPT:#单部门
|
||||
destination_participant = list(User.objects.filter(dept=destination_participant).values_list('id', flat=True))
|
||||
|
||||
elif destination_participant_type == State.PARTICIPANT_TYPE_ROLE:#单角色
|
||||
destination_participant = list(User.objects.filter(roles=destination_participant).values_list('id', flat=True))
|
||||
|
||||
elif destination_participant_type == State.PARTICIPANT_TYPE_FORMCODE:#代码获取
|
||||
destination_participant = getattr(GetParticipants, destination_participant)(state=state, ticket=ticket, ticket_data=ticket_data, request=request)
|
||||
|
||||
elif destination_participant_type == State.PARTICIPANT_TYPE_DEPT:#部门
|
||||
destination_participant = list(User.objects.filter(dept__in=destination_participant).values_list('id', flat=True))
|
||||
|
||||
elif destination_participant_type == State.PARTICIPANT_TYPE_ROLE:#角色
|
||||
user_queryset = User.objects.filter(roles__in=destination_participant)
|
||||
# 如果选择了角色, 需要走过滤策略
|
||||
if ticket.filter_policy == 1:
|
||||
user_queryset = user_queryset.filter(dept=ticket.belong_dept)
|
||||
elif ticket.filter_policy == 2:
|
||||
user_queryset = user_queryset.filter(dept=ticket.create_by.dept)
|
||||
elif ticket.filter_policy == 3:
|
||||
user_queryset = user_queryset.filter(dept=request.user.dept)
|
||||
destination_participant = list(user_queryset.values_list('id', flat=True))
|
||||
if type(destination_participant) == list:
|
||||
destination_participant_type = State.PARTICIPANT_TYPE_MULTI
|
||||
destination_participant = list(set(destination_participant))
|
||||
if len(destination_participant) == 1: # 如果只有一个人
|
||||
destination_participant_type = State.PARTICIPANT_TYPE_PERSONAL
|
||||
destination_participant = destination_participant[0]
|
||||
else:
|
||||
destination_participant_type = State.PARTICIPANT_TYPE_PERSONAL
|
||||
if destination_participant_type == State.PARTICIPANT_TYPE_MULTI:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.db.models import base
|
||||
from rest_framework import urlpatterns
|
||||
from apps.wf.views import CustomFieldViewSet, StateViewSet, TicketFlowViewSet, TicketViewSet, TransitionViewSet, WorkflowViewSet
|
||||
from apps.wf.views import CustomFieldViewSet, FromCodeListView, StateViewSet, TicketFlowViewSet, TicketViewSet, TransitionViewSet, WorkflowViewSet
|
||||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
|
@ -12,6 +12,7 @@ router.register('customfield', CustomFieldViewSet, basename='wf_customfield')
|
|||
router.register('ticket', TicketViewSet, basename='wf_ticket')
|
||||
router.register('ticketflow', TicketFlowViewSet, basename='wf_ticketflow')
|
||||
urlpatterns = [
|
||||
path('participant_from_code', FromCodeListView.as_view()),
|
||||
path('', include(router.urls)),
|
||||
]
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.db.models import query
|
||||
from rest_framework.views import APIView
|
||||
from apps.system.models import User
|
||||
from apps.wf.filters import TicketFilterSet
|
||||
from django.core.exceptions import AppRegistryNotReady
|
||||
|
@ -15,7 +16,16 @@ from apps.wf.services import WfService
|
|||
from rest_framework.exceptions import APIException, PermissionDenied
|
||||
from rest_framework import status
|
||||
from django.db.models import Count
|
||||
from .scripts import GetParticipants
|
||||
|
||||
# Create your views here.
|
||||
class FromCodeListView(APIView):
|
||||
def get(self, request, format=None):
|
||||
"""
|
||||
获取处理人代码列表
|
||||
"""
|
||||
return Response(GetParticipants.all_funcs)
|
||||
|
||||
class WorkflowViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||
perms_map = {'get': '*', 'post': 'workflow_create',
|
||||
'put': 'workflow_update', 'delete': 'workflow_delete'}
|
||||
|
@ -133,7 +143,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
if value == State.STATE_FIELD_REQUIRED:
|
||||
if key not in ticket_data or not ticket_data[key]:
|
||||
raise APIException('字段{}必填'.format(key))
|
||||
ticket = serializer.save(state=start_state, create_by=request.user, act_state=Ticket.TICKET_ACT_STATE_DRAFT) # 先创建出来
|
||||
ticket = serializer.save(state=start_state, create_by=request.user, act_state=Ticket.TICKET_ACT_STATE_DRAFT, belong_dept=request.user.dept) # 先创建出来
|
||||
next_state = WfService.get_next_state_by_transition_and_ticket_info(ticket=ticket, transition=transition)
|
||||
participant_info = WfService.get_ticket_state_participant_info(state=next_state, ticket=ticket, ticket_data=ticket.ticket_data)
|
||||
destination_participant_type = participant_info.get('destination_participant_type', 0)
|
||||
|
@ -201,7 +211,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
if value == State.STATE_FIELD_REQUIRED:
|
||||
if key not in ticket_data or not ticket_data[key]:
|
||||
raise APIException('字段{}必填'.format(key))
|
||||
destination_state = WfService.get_next_state_by_transition_and_ticket_info(ticket, transition, ticket_data)
|
||||
destination_state = WfService.get_next_state_by_transition_and_ticket_info(ticket, transition, ticket_data, request)
|
||||
multi_all_person = ticket.multi_all_person
|
||||
if multi_all_person:
|
||||
multi_all_person[request.user.id] =dict(transition=transition.id)
|
||||
|
|
|
@ -5,6 +5,28 @@ from django.db.models.query import QuerySet
|
|||
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
|
||||
from utils.model import SoftModel, BaseModel
|
||||
from simple_history.models import HistoricalRecords
|
||||
from apps.mtm.models import Material, Step
|
||||
|
||||
class Good(CommonAModel):
|
||||
"""
|
||||
物品
|
||||
"""
|
||||
act_state_choices=(
|
||||
(0, '待执行'),
|
||||
(1, '进行中'),
|
||||
(2, '已完成')
|
||||
)
|
||||
number = models.CharField('物品编号', primary_key=True, null=True, blank=True, max_length=50)
|
||||
m_state = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||
p_state = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True)
|
||||
act_state = models.IntegerField('进行状态', default=0)
|
||||
|
||||
|
||||
class GoodFlow(BaseModel):
|
||||
"""
|
||||
物品流转日志
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Vendor(CommonAModel):
|
||||
|
|
|
@ -10,3 +10,4 @@ drf-yasg==1.20.0
|
|||
psutil==5.8.0
|
||||
pillow==8.3.1
|
||||
opencv-python==4.5.3.56
|
||||
django-celery-results==2.2.0
|
||||
|
|
|
@ -41,6 +41,7 @@ INSTALLED_APPS = [
|
|||
'django.contrib.staticfiles',
|
||||
'corsheaders',
|
||||
'django_celery_beat',
|
||||
'django_celery_results',
|
||||
'drf_yasg',
|
||||
'rest_framework',
|
||||
"django_filters",
|
||||
|
@ -55,7 +56,8 @@ INSTALLED_APPS = [
|
|||
'apps.inm',
|
||||
'apps.sam',
|
||||
'apps.qm',
|
||||
'apps.pm'
|
||||
'apps.pm',
|
||||
# 'apps.wpm'
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -202,6 +204,7 @@ CELERY_BROKER_URL = "redis://redis:6379/0" # 任务存储
|
|||
CELERYD_MAX_TASKS_PER_CHILD = 100 # 每个worker最多执行300个任务就会被销毁,可防止内存泄露
|
||||
CELERY_TIMEZONE = 'Asia/Shanghai' # 设置时区
|
||||
CELERY_ENABLE_UTC = True # 启动时区设置
|
||||
CELERY_RESULT_BACKEND = 'django-db'
|
||||
|
||||
# swagger配置
|
||||
SWAGGER_SETTINGS = {
|
||||
|
|
Loading…
Reference in New Issue