Files
djangoadmin-wiki/DjangoAdmin_Tornado_AntdVue/zh/volume5/code-engine.md
T
2026-09-16 13:28:20 +08:00

202 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
:::tip 本章概要
代码生成引擎的工作原理,包括配置解析、模板渲染、文件写入和自动注册的完整流程。
:::
# 代码生成引擎
`src/modules/generator/code_generator.py` 是代码生成器的执行层,负责接收配置字典、渲染模板、写入文件、自动注册路由和菜单。
## 核心类:CodeGenerator
```python
from modules.generator.code_generator import CodeGenerator
generator = CodeGenerator(config)
generator.generate(auto=True)
```
### 构造参数
| 参数 | 说明 |
|:----|:----|
| `config` | 配置字典(由 `parser.parse()` 或 JSON 文件提供) |
构造时自动:
- 调用 `normalize_config()` 标准化配置(幂等,已标准化的配置原样返回)
- 设置输出目录:`src/modules/{app_name}`
- 初始化 Jinja2 模板环境(`trim_blocks=True`, `lstrip_blocks=True`)
## generate() 主方法
```python
def generate(self, auto=False, request=None):
```
### 执行流程
```
1. 校验输出目录不存在(避免覆盖已有模块)
2. 创建输出目录 src/modules/{app_name}/
3. 准备模板上下文数据
4. 渲染后端模板 → 写入 modules 目录
5. 渲染 endpoint 模板 → 写入 api/v1/endpoints/ 目录
6. 渲染前端模板 → 写入 ui/src/views/ 和 ui/src/api/
7. 自动注册到 router.py
8. 自动创建菜单 + 权限节点
```
### 参数
| 参数 | 说明 |
|:----|:----|
| `auto` | 自动模式(当前无交互差异) |
| `request` | Tornado 请求对象(用于获取操作人信息) |
## 配置标准化
`normalize_config()` 将 parser 产出的配置转为模板可用的标准格式:
```python
# parser 产出的字段
{"name": "type", "db_type": "Integer", "comment": "案例类型:1-类型1 2-类型2"}
# 标准化后
{
"name": "type",
"camel_name": "type", # 驼峰命名
"db_type": "Integer",
"form_type": "int", # Pydantic 类型
"comment": "案例类型:1-类型1 2-类型2",
"py_comment": "案例类型:1-类型1 2-类型2", # 转义后
"default_repr": "1", # 默认值表示
"is_status": False, # 状态字段标识
"is_sort": False, # 排序字段标识
}
```
## 模板上下文
### _prepare_context()
准备后端模板的渲染上下文:
| 变量 | 类型 | 说明 |
|:----|:----|:----|
| `app_name` | str | 模块名(如 `example`) |
| `module_comment` | str | 中文名(如 `案例`) |
| `model_class_name` | str | 类名(如 `Example`) |
| `permission_prefix` | str | 权限前缀(如 `sys:example`) |
| `display_field` | str | 显示字段(如 `name`) |
| `has_sort` | bool | 有排序字段 |
| `has_status` | bool | 有状态字段 |
| `has_status_route` | bool | 生成状态路由 |
| `has_image_field` | bool | 有图片字段 |
| `has_rich_text_field` | bool | 有富文本字段 |
| `serialize_maps` | dict | 枚举映射 |
| `sort_field` | str | 排序字段名 |
| `fields` | list | 全部字段 |
| `form_fields` | list | 表单字段 |
| `filter_fields` | list | 精确匹配字段 |
| `like_fields` | list | 模糊查询字段 |
### _prepare_vue_context()
在后端上下文基础上扩展前端专用变量:
| 变量 | 类型 | 说明 |
|:----|:----|:----|
| `module_name` | str | 驼峰模块名 |
| `model_class_name_camel` | str | 驼峰类名(首字母小写) |
| `list_fields` | list | 列表展示字段 |
| `searchable_fields` | list | 可搜索字段 |
| `editable_fields` | list | 可编辑字段 |
| `has_export` | bool | 有导出功能 |
| `route_prefix` | str | 路由前缀 |
| `api_path` | str | API 路径 |
| `is_tree_structure` | bool | 是否树形结构 |
| `parent_id_field` | str | 父级字段名 |
| `has_search_form` | bool | 显示搜索表单 |
| `show_selection` | bool | 显示复选框 |
## 文件生成
### 后端文件
| 模板 | 输出路径 | 说明 |
|:----|:----|:----|
| `__init__.py.tpl` | `src/modules/{name}/__init__.py` | 模块初始化 |
| `models.py.tpl` | `src/modules/{name}/models.py` | ORM 模型 |
| `schemas.py.tpl` | `src/modules/{name}/schemas.py` | Pydantic 表单 |
| `repository.py.tpl` | `src/modules/{name}/repository.py` | 数据访问层 |
| `service.py.tpl` | `src/modules/{name}/service.py` | 业务逻辑层 |
| `endpoint.py.tpl` | `src/modules/{name}.py` | HTTP 端点 |
### 前端文件(普通列表)
| 模板 | 输出路径 |
|:----|:----|
| `ui/index.vue.tpl` | `ui/src/views/tool/{name}/index.vue` |
| `ui/edit.vue.tpl` | `ui/src/views/tool/{name}/edit.vue` |
| `ui/detail.vue.tpl` | `ui/src/views/tool/{name}/detail.vue` |
| `ui/columns.ts.tpl` | `ui/src/views/tool/{name}/columns.ts` |
| `ui/querySchemas.ts.tpl` | `ui/src/views/tool/{name}/querySchemas.ts` |
| `ui/api.ts.tpl` | `ui/src/api/tool/{name}.ts` |
### 前端文件(树状列表)
| 模板 | 输出路径 |
|:----|:----|
| `ui2/index.vue.tpl` | `ui/src/views/tool/{name}/index.vue` |
| `ui2/edit.vue.tpl` | `ui/src/views/tool/{name}/edit.vue` |
| `ui2/detail.vue.tpl` | `ui/src/views/tool/{name}/detail.vue` |
| `ui/api.ts.tpl` | `ui/src/api/tool/{name}.ts` |
树状列表与普通列表共用 `api.ts.tpl`。
## 自动注册
### 路由注册
`_register_module()` 在 `src/api/v1/router.py` 中追加:
```python
# 导入语句(插入到最后一个 from api.v1.endpoints 导入之后)
from api.v1.endpoints.example import router as example_router
# 注册语句(追加到文件末尾)
v1._RESOURCE_MODULES 追加(example_router, prefix="/example", tags=["案例"])
```
幂等操作:如果导入语句已存在,跳过。
### 菜单创建
`_create_menus()` 在数据库中创建:
1. **二级菜单**(type=0):页面路由
- name: 模块中文名
- path: `/tool/{module_camel}`
- component: `/tool/{module_camel}/index`
- parent_id: 189(开发工具)
2. **三级权限节点**(type=1)× 10 个:
| 权限 | 标识 |
|:----|:----|
| 分页查询 | `{prefix}:page` |
| 列表查询 | `{prefix}:list` |
| 详情查询 | `{prefix}:detail` |
| 新增 | `{prefix}:add` |
| 编辑 | `{prefix}:update` |
| 删除 | `{prefix}:delete` |
| 批量删除 | `{prefix}:batchDelete` |
| 状态管理 | `{prefix}:status` |
| 导入 | `{prefix}:import` |
| 导出 | `{prefix}:export` |
幂等操作:如果 path 已存在,跳过。创建后自动清除所有用户权限缓存。
## 总结
代码生成引擎根据数据库表结构和配置信息,通过 Jinja2 模板渲染生成后端(models/schemas/repository/service/endpoint)和前端(index.vue/edit.vue/columns.ts/querySchemas.ts/api.ts)全套代码,生成后自动注册路由和权限。