first commit
This commit is contained in:
260
code/system/management/commands/generator.py
Normal file
260
code/system/management/commands/generator.py
Normal file
@@ -0,0 +1,260 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from fuadmin.settings import BASE_DIR
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""
|
||||
创建App命令:
|
||||
python manage.py createapp app名
|
||||
python manage.py createapp app01 app02 ...
|
||||
python manage.py createapp 一级文件名/app01 ... # 支持多级目录建app
|
||||
"""
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('app_info', nargs='*', type=str, )
|
||||
|
||||
def handle(self, *args, **options):
|
||||
app_info = options.get('app_info')
|
||||
for name in app_info:
|
||||
app = json.loads(name)
|
||||
name = app.get('app_name')
|
||||
names = name.split('/')
|
||||
dnames = ".".join(names)
|
||||
app_path = os.path.join(BASE_DIR, "dvadmin", *names)
|
||||
# 判断app是否存在
|
||||
if os.path.exists(app_path):
|
||||
print(f"App {name} 已存在!")
|
||||
# break
|
||||
else:
|
||||
source_path = os.path.join(BASE_DIR, "dvadmin", "utils", "template")
|
||||
target_path = app_path
|
||||
if not os.path.exists(target_path):
|
||||
# 如果目标路径不存在原文件夹的话就创建
|
||||
os.makedirs(target_path)
|
||||
if os.path.exists(source_path):
|
||||
# 如果目标路径存在原文件夹的话就先删除
|
||||
shutil.rmtree(target_path)
|
||||
shutil.copytree(source_path, target_path)
|
||||
# 注册app到 settings.py 中
|
||||
injection(os.path.join(BASE_DIR, "application", "settings.py"), f" 'dvadmin.{dnames}',\n",
|
||||
"INSTALLED_APPS",
|
||||
"]")
|
||||
|
||||
# 注册app到 urls.py 中
|
||||
injection(os.path.join(BASE_DIR, "application", "urls.py"),
|
||||
f" path(r'api/{name}/', include('dvadmin.{dnames}.urls')),\n", "urlpatterns = [",
|
||||
"]")
|
||||
|
||||
# 修改app中的apps 内容
|
||||
app_content = f"""
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class {name.capitalize()}Config(AppConfig):
|
||||
name = 'dvadmin.{dnames}'
|
||||
verbose_name = "{names[-1]}App"
|
||||
"""
|
||||
with open(os.path.join(app_path, "apps.py"), 'w', encoding='UTF-8') as f:
|
||||
f.write(app_content)
|
||||
|
||||
# 修改Model的内容
|
||||
|
||||
table_name = app.get('table_name')
|
||||
model_name = app.get('model_name')
|
||||
|
||||
# app中所有不重复的字段
|
||||
app_fields = app.get('fields')
|
||||
field_content = ''
|
||||
# app中所有不重复的字段type
|
||||
fields_type = set()
|
||||
# app中所有的字段name
|
||||
fields_name = set()
|
||||
for field in app_fields:
|
||||
fields_type.add(field['type'])
|
||||
fields_name.add(field['name'])
|
||||
if field['type'] == 'CharField':
|
||||
field_content = f"""{field_content}
|
||||
{field['name']} = {field['type']}(max_length={field['max_length']}, verbose_name='{field['name']}', help_text='{field['description']}')"""
|
||||
elif field['type'] == 'TextField':
|
||||
field_content = f"""{field_content}
|
||||
{field['name']} = {field['type']}(verbose_name='{field['name']}', help_text='{field['description']}')"""
|
||||
model_content = f"""
|
||||
from django.db.models import {','.join(fields_type)}
|
||||
from dvadmin.utils.models import CoreModel
|
||||
|
||||
|
||||
class {model_name}(CoreModel):
|
||||
{field_content}
|
||||
|
||||
class Meta:
|
||||
verbose_name = '{model_name}'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.{fields_name.pop()}
|
||||
"""
|
||||
|
||||
with open(os.path.join(app_path, "models", f"{table_name}.py"), 'w', encoding='UTF-8') as f:
|
||||
f.write(model_content)
|
||||
|
||||
# 修改 model init文件
|
||||
model_init_content = f"from dvadmin.{name}.models.{table_name} import {model_name}"
|
||||
with open(os.path.join(app_path, "models", "__init__.py"), 'a', encoding='UTF-8') as f:
|
||||
f.write(model_init_content)
|
||||
f.write('\n')
|
||||
|
||||
# 修改filters的内容
|
||||
filter_content = f"""
|
||||
import django_filters
|
||||
from dvadmin.{name}.models import {model_name}
|
||||
|
||||
|
||||
class {model_name}Filter(django_filters.rest_framework.FilterSet):
|
||||
|
||||
# 通过 lookup_expr 可进行模糊查询,其他配置可自行百度
|
||||
# name = django_filters.CharFilter(lookup_expr='icontains')
|
||||
|
||||
class Meta:
|
||||
model = {model_name}
|
||||
fields = '__all__'
|
||||
|
||||
"""
|
||||
with open(os.path.join(app_path, "filters", f"{table_name}_filter.py"), 'w', encoding='UTF-8') as f:
|
||||
f.write(filter_content)
|
||||
|
||||
# 修改 filters init文件
|
||||
filter_init_content = f"from .{table_name}_filter import {model_name}Filter"
|
||||
with open(os.path.join(app_path, "filters", "__init__.py"), 'a', encoding='UTF-8') as f:
|
||||
f.write(filter_init_content)
|
||||
f.write('\n')
|
||||
|
||||
# 修改serializers的内容
|
||||
serializer_content = f"""
|
||||
from rest_framework import serializers
|
||||
from dvadmin.{name}.models import {model_name}
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
|
||||
|
||||
class {model_name}Serializer(CustomModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = {model_name}
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class {model_name}CreateUpdateSerializer(CustomModelSerializer):
|
||||
|
||||
# 此处可写定制的 创建/更新 内容
|
||||
def validate(self, attrs: dict):
|
||||
return super().validate(attrs)
|
||||
|
||||
class Meta:
|
||||
model = {model_name}
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class {model_name}ImportSerializer(CustomModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = {model_name}
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class {model_name}ExportSerializer(CustomModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = {model_name}
|
||||
fields = '__all__'
|
||||
|
||||
"""
|
||||
with open(os.path.join(app_path, 'serializers', f'{table_name}_serializer.py'), 'w', encoding='UTF-8') as f:
|
||||
f.write(serializer_content)
|
||||
|
||||
# 修改 serializers init文件
|
||||
serializer_init_content = f"from .{table_name}_serializer import {model_name}Serializer, " \
|
||||
f"{model_name}CreateUpdateSerializer, " \
|
||||
f"{model_name}ImportSerializer, " \
|
||||
f"{model_name}ExportSerializer"
|
||||
with open(os.path.join(app_path, "serializers", "__init__.py"), 'a', encoding='UTF-8') as f:
|
||||
f.write(serializer_init_content)
|
||||
f.write('\n')
|
||||
# 修改view内容
|
||||
view_content = f"""
|
||||
from dvadmin.utils.filters import DataLevelPermissionsFilter
|
||||
from dvadmin.utils.viewset import CustomModelViewSet
|
||||
from dvadmin.{name}.models import {model_name}
|
||||
from dvadmin.{name}.filters import {model_name}Filter
|
||||
from dvadmin.{name}.serializers import {model_name}Serializer, {model_name}CreateUpdateSerializer, {model_name}ImportSerializer, {model_name}ExportSerializer
|
||||
|
||||
|
||||
class {model_name}ModelViewSet(CustomModelViewSet):
|
||||
|
||||
queryset = {model_name}.objects.all()
|
||||
serializer_class = {model_name}Serializer # 序列化器
|
||||
create_serializer_class = {model_name}CreateUpdateSerializer # 创建/更新时的列化器
|
||||
update_serializer_class = {model_name}CreateUpdateSerializer # 创建/更新时的列化器
|
||||
filter_class = {model_name}Filter # 过滤器
|
||||
extra_filter_backends = [DataLevelPermissionsFilter] # 数据权限类,不需要可注释掉
|
||||
# ordering = ['create_datetime'] # 默认排序
|
||||
# 导出
|
||||
export_field_data = [] # 导出
|
||||
export_serializer_class = {model_name}ExportSerializer # 导出序列化器
|
||||
# 导入
|
||||
import_field_data = []
|
||||
import_serializer_class = {model_name}ImportSerializer
|
||||
|
||||
|
||||
"""
|
||||
with open(os.path.join(app_path, 'views', f'{table_name}_view.py'), 'w', encoding='UTF-8') as f:
|
||||
f.write(view_content)
|
||||
|
||||
# 修改 views init文件
|
||||
view_init_content = f"from .{table_name}_view import {model_name}ModelViewSet"
|
||||
with open(os.path.join(app_path, "views", "__init__.py"), 'a', encoding='UTF-8') as f:
|
||||
f.write(view_init_content)
|
||||
f.write('\n')
|
||||
|
||||
# 修改 url文件
|
||||
url_package = f"from dvadmin.{name}.views import {model_name}ModelViewSet"
|
||||
injection(os.path.join(app_path, "urls.py"),
|
||||
f"{url_package}\n", "from rest_framework.routers import DefaultRouter",
|
||||
"router = DefaultRouter()")
|
||||
|
||||
url_path = f"router.register(r'{table_name}', {model_name}ModelViewSet)"
|
||||
injection(os.path.join(app_path, "urls.py"),
|
||||
f"{url_path}\n", "router = DefaultRouter()",
|
||||
"urlpatterns = [")
|
||||
|
||||
export_import_url = f""" # 导出项目
|
||||
path('{table_name}/export/', {model_name}ModelViewSet.as_view({{'get': 'export', }})),
|
||||
# 项目导入模板下载及导入
|
||||
path('{table_name}/importTemplate/', {model_name}ModelViewSet.as_view({{'get': 'importTemplate', 'post': 'importTemplate'}}))"""
|
||||
injection(os.path.join(app_path, "urls.py"),
|
||||
f"{export_import_url}\n", "urlpatterns = [", "]")
|
||||
|
||||
print(f"创建 {name} App成功")
|
||||
|
||||
|
||||
def injection(file_path, insert_content, startswith, endswith):
|
||||
with open(file_path, "r+", encoding="utf-8") as f:
|
||||
data = f.readlines()
|
||||
with open(file_path, 'w', encoding='UTF-8') as f1:
|
||||
is_INSTALLED_APPS = False
|
||||
is_insert = False
|
||||
for content in data:
|
||||
# 判断文件是否 INSTALLED_APPS 开头
|
||||
if not is_insert and content.startswith(startswith):
|
||||
is_INSTALLED_APPS = True
|
||||
if not is_insert and content.startswith(endswith) and is_INSTALLED_APPS:
|
||||
# 给前一行插入数据
|
||||
content = insert_content + content
|
||||
is_insert = True
|
||||
f1.writelines(content)
|
||||
Reference in New Issue
Block a user