功能变化: 优化系统配置及字典管理,支持tenants模式

pull/57/head
李强 2022-05-15 14:32:22 +08:00
parent dbee7dd060
commit ffa5c8ec60
8 changed files with 210 additions and 99 deletions

View File

@ -3,9 +3,9 @@ import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings')
from django.conf import settings from django.conf import settings
from application import dispatch
from celery import platforms from celery import platforms
if dispatch.is_tenants_mode():
if 'dvadmin_tenant' in settings.REGISTER_PLUGINS:
from tenant_schemas_celery.app import CeleryApp as TenantAwareCeleryApp from tenant_schemas_celery.app import CeleryApp as TenantAwareCeleryApp
app = TenantAwareCeleryApp() app = TenantAwareCeleryApp()
else: else:

View File

@ -0,0 +1,190 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.conf import settings
from django.db import ProgrammingError
from django.db import connection
def is_tenants_mode():
"""
判断是否为租户模式
:return:
"""
return hasattr(connection, 'tenant') and connection.tenant.schema_name
# ================================================= #
# ******************** 初始化 ******************** #
# ================================================= #
def _get_all_dictionary():
from dvadmin.system.models import Dictionary
queryset = Dictionary.objects.filter(status=True, is_value=False)
data = []
for instance in queryset:
data.append({
"id": instance.id,
"value": instance.value,
"children": list(Dictionary.objects.filter(parent=instance.id).filter(status=1).
values('label', 'value', 'type', 'color'))
})
return {ele.get("value"): ele for ele in data}
def _get_all_system_config():
data = {}
from dvadmin.system.models import SystemConfig
system_config_obj = SystemConfig.objects.filter(status=True, parent_id__isnull=False).values(
'parent__key', 'key', 'value', 'form_item_type').order_by('sort')
for system_config in system_config_obj:
data[f"{system_config.get('parent__key')}.{system_config.get('key')}"] = system_config.get('value') or ''
return data
def init_dictionary(schema_name=None):
"""
初始化字典配置
:return:
"""
try:
if is_tenants_mode():
from django_tenants.utils import tenant_context
for tenant in get_tenant_model().objects.filter(schema_name=schema_name):
with tenant_context(tenant):
settings.DICTIONARY_CONFIG[connection.tenant.schema_name] = _get_all_dictionary()
else:
settings.DICTIONARY_CONFIG = _get_all_dictionary()
print("初始化字典配置完成")
except ProgrammingError as e:
print("请先进行数据库迁移!")
return
def init_system_config():
"""
初始化系统配置
:param name:
:return:
"""
try:
if is_tenants_mode():
from django_tenants.utils import tenant_context
for tenant in get_tenant_model().objects.filter(schema_name=schema_name):
with tenant_context(tenant):
settings.SYSTEM_CONFIG[connection.tenant.schema_name] = _get_all_system_config()
else:
settings.SYSTEM_CONFIG = _get_all_system_config()
print("初始化系统配置完成")
except ProgrammingError as e:
print("请先进行数据库迁移!")
return
def refresh_dictionary():
"""
刷新字典配置
:return:
"""
if is_tenants_mode():
with schema_context(connection.tenant.schema_name):
settings.DICTIONARY_CONFIG[connection.tenant.schema_name] = _get_all_dictionary()
else:
settings.DICTIONARY_CONFIG = _get_all_dictionary()
def refresh_system_config():
"""
刷新系统配置
:return:
"""
if is_tenants_mode():
with schema_context(connection.tenant.schema_name):
settings.SYSTEM_CONFIG[connection.tenant.schema_name] = _get_all_system_config()
else:
settings.SYSTEM_CONFIG = _get_all_system_config()
# ================================================= #
# ******************** 字典管理 ******************** #
# ================================================= #
def get_dictionary_config(schema_name=None):
"""
获取字典所有配置
:param schema_name: 对应字典配置的租户schema_name值
:return:
"""
if is_tenants_mode():
dictionary_config = settings.DICTIONARY_CONFIG[schema_name or connection.tenant.schema_name]
else:
dictionary_config = settings.DICTIONARY_CONFIG
return dictionary_config or {}
def get_dictionary_values(key, schema_name=None):
"""
获取字典数据数组
:param key: 对应字典配置的key值(字典编号)
:param schema_name: 对应字典配置的租户schema_name值
:return:
"""
dictionary_config = get_dictionary_config(schema_name)
return dictionary_config.get(key)
def get_dictionary_label(key, name, schema_name=None):
"""
获取获取字典label值
:param key: 字典管理中的key值(字典编号)
:param name: 对应字典配置的value值
:param schema_name: 对应字典配置的租户schema_name值
:return:
"""
children = get_dictionary_values(key, schema_name) or []
for ele in children:
if ele.get("value") == str(name):
return ele.get("label")
return ""
# ================================================= #
# ******************** 系统配置 ******************** #
# ================================================= #
def get_system_config(schema_name=None):
"""
获取系统配置中所有配置
1.只传父级的key返回全部子级{ "父级key.子级key" : "" }
2."父级key.子级key"返回子级值
:param schema_name: 对应字典配置的租户schema_name值
:return:
"""
if is_tenants_mode():
dictionary_config = settings.SYSTEM_CONFIG[schema_name or connection.tenant.schema_name]
else:
dictionary_config = settings.SYSTEM_CONFIG
return dictionary_config or {}
def get_system_config_values(key, schema_name=None):
"""
获取系统配置数据数组
:param key: 对应系统配置的key值(字典编号)
:param schema_name: 对应系统配置的租户schema_name值
:return:
"""
system_config = get_system_config(schema_name)
return system_config.get(key)
def get_system_config_label(key, name, schema_name=None):
"""
获取获取系统配置label值
:param key: 系统配置中的key值(字典编号)
:param name: 对应系统配置的value值
:param schema_name: 对应系统配置的租户schema_name值
:return:
"""
children = get_system_config_values(key, schema_name) or []
for ele in children:
if ele.get("value") == str(name):
return ele.get("label")
return ""

View File

@ -355,10 +355,6 @@ CELERY_TIMEZONE = "Asia/Shanghai" # celery 时区问题
STATICFILES_STORAGE = "whitenoise.storage.CompressedStaticFilesStorage" STATICFILES_STORAGE = "whitenoise.storage.CompressedStaticFilesStorage"
ALL_MODELS_OBJECTS = [] # 所有app models 对象 ALL_MODELS_OBJECTS = [] # 所有app models 对象
# dvadmin 插件
REGISTER_PLUGINS = (
# ""
)
# 初始化需要执行的列表,用来初始化后执行 # 初始化需要执行的列表,用来初始化后执行
INITIALIZE_LIST = [] INITIALIZE_LIST = []

View File

@ -23,7 +23,7 @@ from rest_framework_simplejwt.views import (
) )
from application import settings from application import settings
from dvadmin.system.models import SystemConfig, Dictionary from application import dispatch
from dvadmin.system.views.dictionary import InitDictionaryViewSet from dvadmin.system.views.dictionary import InitDictionaryViewSet
from dvadmin.system.views.login import ( from dvadmin.system.views.login import (
LoginView, LoginView,
@ -35,8 +35,8 @@ from dvadmin.system.views.system_config import InitSettingsViewSet
from dvadmin.utils.swagger import CustomOpenAPISchemaGenerator from dvadmin.utils.swagger import CustomOpenAPISchemaGenerator
# =========== 初始化系统配置 ================= # =========== 初始化系统配置 =================
SystemConfig.init_system_config() dispatch.init_system_config()
Dictionary.init_dictionary() dispatch.init_dictionary()
# =========== 初始化系统配置 ================= # =========== 初始化系统配置 =================
schema_view = get_schema_view( schema_view = get_schema_view(

View File

@ -13,6 +13,8 @@ import pypinyin
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.db import connection from django.db import connection
from application import dispatch
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings')
django.setup() django.setup()
from application.settings import BASE_DIR from application.settings import BASE_DIR
@ -45,7 +47,7 @@ def area_list(code_list, pcode=None, depth=1):
def main(): def main():
with open(os.path.join(BASE_DIR, 'dvadmin', 'system', 'util', 'pca-code.json'), 'r',encoding="utf-8") as load_f: with open(os.path.join(BASE_DIR, 'dvadmin', 'system', 'util', 'pca-code.json'), 'r', encoding="utf-8") as load_f:
code_list = json.load(load_f) code_list = json.load(load_f)
area_list(code_list) area_list(code_list)
if Area.objects.count() == 0: if Area.objects.count() == 0:
@ -68,9 +70,9 @@ class Command(BaseCommand):
print(f"正在准备初始化省份数据...") print(f"正在准备初始化省份数据...")
if hasattr(connection, 'tenant') and connection.tenant.schema_name: if dispatch.is_tenants_mode():
from django_tenants.utils import get_tenant_model from django_tenants.utils import get_tenant_model
from django_tenants.utils import tenant_context,schema_context from django_tenants.utils import tenant_context
for tenant in get_tenant_model().objects.exclude(schema_name='public'): for tenant in get_tenant_model().objects.exclude(schema_name='public'):
with tenant_context(tenant): with tenant_context(tenant):
print(f"租户[{connection.tenant.schema_name}]初始化数据开始...") print(f"租户[{connection.tenant.schema_name}]初始化数据开始...")
@ -79,4 +81,3 @@ class Command(BaseCommand):
else: else:
main() main()
print("省份数据初始化数据完成!") print("省份数据初始化数据完成!")

View File

@ -1,10 +1,10 @@
import hashlib import hashlib
import os import os
from django.conf import settings
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db import models, ProgrammingError from django.db import models
from application import dispatch
from dvadmin.utils.models import CoreModel, table_prefix from dvadmin.utils.models import CoreModel, table_prefix
STATUS_CHOICES = ( STATUS_CHOICES = (
@ -195,37 +195,9 @@ class Dictionary(CoreModel):
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
ordering = ('sort',) ordering = ('sort',)
@classmethod def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
def init_dictionary(cls): super().save(force_insert, force_update, using, update_fields)
try: dispatch.refresh_dictionary() # 有更新则刷新字典配置
queryset = cls.objects.filter(status=True, is_value=False)
data = []
for instance in queryset:
data.append({
"id": instance.id,
"value": instance.value,
"children": list(cls.objects.filter(parent=instance.id).filter(status=1).
values('label', 'value', 'type', 'color'))
})
settings.DICTIONARY_CONFIG = {ele.get("value"): ele for ele in data}
print("初始化字典配置完成")
except ProgrammingError as e:
print("请先进行数据库迁移!")
return
@classmethod
def get_dictionary_label(cls, key, name):
"""
获取获取字典label值
:param key: 字典管理中的key
:param name: 对应字典配置的value值
:return:
"""
children = settings.DICTIONARY_CONFIG.get(key) or []
for ele in children:
if ele.get("value") == str(name):
return ele.get("label")
return ""
class OperationLog(CoreModel): class OperationLog(CoreModel):
@ -358,57 +330,7 @@ class SystemConfig(CoreModel):
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
super().save(force_insert, force_update, using, update_fields) super().save(force_insert, force_update, using, update_fields)
self.init_system_config() dispatch.refresh_system_config() # 有更新则刷新系统配置
@classmethod
def get_system_config(cls, name):
"""
1.只传父级的key返回全部子级{ "父级key.子级key" : "" }
2."父级key.子级key"返回子级值
:param name:
:return:
"""
key_list = name.split('.')
if len(key_list) > 2:
return ""
elif len(key_list) == 2:
parent_key = key_list[0]
children_key = key_list[1]
instance = cls.objects.filter(parent__key=parent_key, key=children_key, status=True).first()
return instance.value if instance else ""
elif len(key_list) == 1:
instance = cls.objects.filter(key=key_list[0], status=True, parent_id__isnull=True).first()
if not instance:
return ""
system_config_obj = cls.objects.filter(parent_id=instance.id, status=True).values(
'parent__key', 'key', 'value', 'form_item_type').order_by('sort')
data = {}
for system_config in system_config_obj:
data[f"{system_config.get('parent__key')}.{system_config.get('key')}"] = system_config.get(
'value') or ''
return data
return ""
@classmethod
def init_system_config(cls):
"""
初始化系统配置
:param name:
:return:
"""
try:
data = {}
system_config_obj = SystemConfig.objects.filter(status=True, parent_id__isnull=False).values(
'parent__key', 'key', 'value', 'form_item_type').order_by('sort')
for system_config in system_config_obj:
data[f"{system_config.get('parent__key')}.{system_config.get('key')}"] = system_config.get('value') or ''
settings.SYSTEM_CONFIG = data
print("初始化系统配置完成")
except ProgrammingError as e:
print("请先进行数据库迁移!")
return
class LoginLog(CoreModel): class LoginLog(CoreModel):

View File

@ -9,6 +9,7 @@
from django.conf import settings from django.conf import settings
from rest_framework.views import APIView from rest_framework.views import APIView
from application import dispatch
from dvadmin.system.models import Dictionary from dvadmin.system.models import Dictionary
from dvadmin.utils.json_response import SuccessResponse from dvadmin.utils.json_response import SuccessResponse
from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.serializers import CustomModelSerializer
@ -63,7 +64,7 @@ class InitDictionaryViewSet(APIView):
dictionary_key = self.request.query_params.get('dictionary_key') dictionary_key = self.request.query_params.get('dictionary_key')
if dictionary_key: if dictionary_key:
if dictionary_key == 'all': if dictionary_key == 'all':
data = [ele for ele in settings.DICTIONARY_CONFIG.values()] data = [ele for ele in dispatch.get_dictionary_config().values()]
else: else:
data = self.queryset.filter(parent__value=dictionary_key, status=True).values('label', 'value', 'type', data = self.queryset.filter(parent__value=dictionary_key, status=True).values('label', 'value', 'type',
'color') 'color')

View File

@ -13,6 +13,7 @@ from django_filters.rest_framework import BooleanFilter
from rest_framework import serializers from rest_framework import serializers
from rest_framework.views import APIView from rest_framework.views import APIView
from application import dispatch
from dvadmin.system.models import SystemConfig from dvadmin.system.models import SystemConfig
from dvadmin.utils.json_response import DetailResponse, SuccessResponse, ErrorResponse from dvadmin.utils.json_response import DetailResponse, SuccessResponse, ErrorResponse
from dvadmin.utils.models import get_all_models_objects from dvadmin.utils.models import get_all_models_objects
@ -207,4 +208,4 @@ class InitSettingsViewSet(APIView):
permission_classes = [] permission_classes = []
def get(self, request): def get(self, request):
return DetailResponse(data=settings.SYSTEM_CONFIG) return DetailResponse(data=dispatch.get_system_config())