# 第四章 架构设计 - 扩展性设计 ## 4.1 扩展性设计原则 项目遵循开闭原则(OCP):对扩展开放,对修改关闭。新功能通过添加新模块实现,而非修改现有代码。系统通过 Django App 机制、代码生成器、模板定制等方式提供扩展能力。 ## 4.2 Django App 机制 ### 4.2.1 模块化设计 每个业务模块独立为一个 Django App,可独立开发、测试和部署: ``` application/ +-- example/ # 案例模块 | +-- __init__.py | +-- apps.py # 应用配置 | +-- models.py # 数据模型 | +-- forms.py # 表单验证 | +-- services.py # 业务逻辑 | +-- views.py # 视图处理 | +-- urls.py # 路由配置 | +-- user/ # 用户模块 +-- role/ # 角色模块 +-- ... # 其他模块 ``` ### 4.2.2 应用注册 新模块需要在 `application/settings.py` 中注册: ```python INSTALLED_APPS = [ # ... 其他应用 'application.example', # 注册案例模块 ] ``` ### 4.2.3 路由注册 新模块需要在 `application/urls.py` 中注册路由: ```python urlpatterns = [ # ... 其他路由 path('example/', include('application.example.urls')), ] ``` ## 4.3 代码生成器 ### 4.3.1 生成器概述 代码生成器是 核心功能,通过数据库表定义自动生成完整的 CRUD 模块,包括: - 后端:Model、Form、Service、View、URL、Admin - 前端:Vue 页面、API 模块、表格列配置、查询表单配置 - 数据库:迁移文件、菜单记录、权限节点 ### 4.3.2 使用方式 ```bash # 从数据库表生成配置 python generator.py django_ # 从配置文件生成代码 python generator.py --config config.json # 仅预览配置,不生成代码 python generator.py django_
--dry-run ``` ### 4.3.3 生成器工作流程 ``` 1. 解析数据库表结构 +-- 获取字段名、类型、注释、长度、索引 +-- 启发式分类字段(图片、富文本、状态、排序等) | v 2. 生成配置文件 (config.json) +-- 模块名称、表名、字段定义 +-- 前端组件类型、验证规则 | v 3. 渲染 Jinja2 模板 +-- 后端模板:models.py.tpl, forms.py.tpl, services.py.tpl 等 +-- 前端模板:index.vue.tpl, edit.vue.tpl, api.ts.tpl 等 | v 4. 写入文件 +-- application// # 后端模块 +-- ui/src/views/... # 前端页面 +-- ui/src/api/... # API模块 | v 5. 自动注册 +-- 执行 makemigrations/migrate +-- 插入菜单和权限节点 +-- 追加路由到 application/urls.py +-- 追加应用到 INSTALLED_APPS ``` ### 4.3.4 配置文件格式 ```json { "appName": "example", "tableName": "django_example", "tableComment": "案例表", "className": "Example", " moduleName": "案例", "fields": [ { "fieldName": "name", "fieldType": "CharField", "fieldComment": "案例名称", "maxLength": 100, "isRequired": true, "isSearch": true, "componentType": "input" }, { "fieldName": "status", "fieldType": "IntegerField", "fieldComment": "案例状态", "choices": [ {"value": 1, "label": "正常"}, {"value": 2, "label": "禁用"} ], "componentType": "select" } ] } ``` ## 4.4 模板定制 ### 4.4.1 模板目录 代码生成器使用 Jinja2 模板,模板文件位于 `public/templates/` 目录: ``` public/templates/ +-- models.py.tpl # 模型模板 +-- forms.py.tpl # 表单模板 +-- services.py.tpl # 服务模板 +-- views.py.tpl # 视图模板 +-- urls.py.tpl # 路由模板 +-- apps.py.tpl # 应用配置模板 +-- admin.py.tpl # Admin注册模板 +-- migration.py.tpl # 迁移文件模板 +-- ui/ +-- index.vue.tpl # 列表页模板 +-- edit.vue.tpl # 编辑页模板 +-- detail.vue.tpl # 详情页模板 +-- api.ts.tpl # API模块模板 +-- columns.ts.tpl # 表格列配置模板 +-- querySchemas.ts.tpl # 查询表单配置模板 ``` ### 4.4.2 模板语法示例 ```jinja2 {# models.py.tpl #} from django.db import models from application.models import BaseModel from utils.common import get_table_name class {{ className }}(BaseModel): """{{ tableComment }}""" {% for field in fields %} {{ field.fieldName }} = models.{{ field.fieldType }}( {% if field.maxLength %} max_length={{ field.maxLength }},{% endif %} {% if not field.isRequired %} null=True, blank=True,{% endif %} verbose_name="{{ field.fieldComment }}", db_comment='{{ field.fieldComment }}' ) {% endfor %} class Meta: db_table = get_table_name('{{ appName }}') db_table_comment = "{{ tableComment }}" ``` ### 4.4.3 自定义模板 开发者可以根据项目需求定制模板: 1. 修改 `public/templates/` 目录下的模板文件 2. 使用 Jinja2 语法添加自定义逻辑 3. 重新运行代码生成器应用新的模板 ## 4.5 中间件扩展 ### 4.5.1 自定义中间件 通过 Django 中间件机制可灵活添加请求/响应处理逻辑: ```python # middleware/custom_middleware.py class CustomMiddleware: """自定义中间件""" def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 请求处理前的逻辑 # ... response = self.get_response(request) # 响应处理后的逻辑 # ... return response ``` ### 4.5.2 注册中间件 在 `application/settings.py` 中注册自定义中间件: ```python MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'middleware.custom_middleware.CustomMiddleware', # 注册自定义中间件 # ... 其他中间件 ] ``` ## 4.6 信号机制扩展 ### 4.6.1 Django 信号 Django 提供信号机制,可以在特定事件发生时执行自定义逻辑: ```python from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=Example) def example_post_save(sender, instance, created, **kwargs): """案例保存后的处理""" if created: # 新增记录后的逻辑 pass else: # 更新记录后的逻辑 pass ``` ### 4.6.2 内置信号 | 信号 | 触发时机 | 说明 | |------|----------|------| | `pre_save` | 保存前 | 数据验证前 | | `post_save` | 保存后 | 数据保存后 | | `pre_delete` | 删除前 | 删除前检查 | | `post_delete` | 删除后 | 清理关联数据 | | `class_prepared` | 模型类准备就绪 | 字段顺序重排 | ## 4.7 自定义管理命令 ### 4.7.1 创建管理命令 ```python # application/management/commands/my_command.py from django.core.management.base import BaseCommand class Command(BaseCommand): help = '自定义管理命令说明' def add_arguments(self, parser): parser.add_argument('arg1', type=str, help='参数说明') def handle(self, *args, **options): arg1 = options['arg1'] # 命令逻辑 self.stdout.write(self.style.SUCCESS(f'执行成功: {arg1}')) ``` ### 4.7.2 使用管理命令 ```bash python manage.py my_command value1 ``` ### 4.7.3 内置管理命令 ```bash python manage.py runserver # 启动开发服务器 python manage.py makemigrations # 生成迁移文件 python manage.py migrate # 执行迁移 python manage.py createsuperuser # 创建超级用户 python manage.py add_full_comments # 回填数据库字段注释 ``` ## 4.8 前端扩展 ### 4.8.1 动态路由 前端路由由后端菜单数据动态生成,新页面通过插入菜单记录自动注册: ```sql INSERT INTO django_menu (name, path, component, permission, type, status) VALUES ('案例管理', '/example', 'tool/example/index', 'sys:example:page', 0, 0); ``` ### 4.8.2 组件扩展 前端使用 Vue3 + ElementPlus,可通过以下方式扩展: 1. **自定义组件**:在 `ui/src/components/` 目录下创建新组件 2. **组合式函数**:在 `ui/src/hooks/` 目录下创建自定义 hooks 3. **全局指令**:在 `ui/src/directives/` 目录下创建自定义指令 ### 4.8.3 API 扩展 新增 API 接口需要在 `ui/src/api/` 目录下创建对应的 TypeScript 模块: ```typescript // ui/src/api/tool/example.ts import { http } from '@/utils/http/axios' export function getExamplePage(params) { return http.get('/example/page', params) } export function addExample(data) { return http.post('/example/add', data) } ``` ## 4.9 扩展性最佳实践 ### 新增模块流程 1. **设计数据库表**:确定字段和关联关系 2. **使用代码生成器**:`python generator.py django_
` 3. **调整生成代码**:根据业务需求修改 Service 层逻辑 4. **注册菜单权限**:通过管理后台或直接操作数据库 5. **前端页面定制**:调整 Vue 页面的表格列和表单字段 ### 扩展注意事项 1. **遵循规范**:保持与现有模块一致的代码风格 2. **软删除**:所有查询都要过滤 `is_delete=False` 3. **权限节点**:为每个操作定义 `sys::` 权限 4. **响应格式**:统一使用 `R.ok()` 和 `R.failed()` 返回响应 5. **操作日志**:使用 `@operation_log` 装饰器记录操作日志