签入版本
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
:::tip 本章概要
|
||||
代码生成器 CLI 模式的使用方法,包括单表生成、预览模式和配置导出。
|
||||
:::
|
||||
|
||||
# CLI 命令行使用
|
||||
|
||||
CLI 入口为项目根目录的 `generator.py`,内部包含 `TableSchemaParser` 解析器,并调用 `generator_config.py` 中的 `CodeGenerator` 引擎。适合开发阶段快速生成单个模块。
|
||||
|
||||
## 基本用法
|
||||
|
||||
```bash
|
||||
# 解析表结构并生成模块(最常用)
|
||||
python generator.py django_example
|
||||
```
|
||||
|
||||
执行后自动完成:
|
||||
1. 从数据库解析 `django_example` 表结构
|
||||
2. 生成后端模块代码到 `application/example/`
|
||||
3. 生成前端页面到 `ui/src/views/tool/example/` 和 `ui/src/api/tool/example.ts`
|
||||
4. 自动追加路由到 `application/urls.py`
|
||||
5. 自动注册应用到 `settings.py` 的 `INSTALLED_APPS`
|
||||
6. 自动创建菜单和权限节点
|
||||
|
||||
## 预览模式
|
||||
|
||||
使用 `--dry-run` 仅解析表结构并打印配置摘要,不执行代码生成:
|
||||
|
||||
```bash
|
||||
python generator.py django_example --dry-run
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
==============================================================
|
||||
数据库表结构解析和代码生成工具
|
||||
==============================================================
|
||||
正在解析表: django_example
|
||||
表结构解析成功
|
||||
|
||||
------------------------------------------------------------
|
||||
生成配置摘要:
|
||||
------------------------------------------------------------
|
||||
应用名称: example
|
||||
模块名称: 案例
|
||||
模型类名: Example
|
||||
字段数量: 5
|
||||
是否有排序: True
|
||||
是否有状态: True
|
||||
|
||||
字段列表:
|
||||
- name: 案例名称 (CharField)
|
||||
- avatar: 案例图片 (CharField)
|
||||
- type: 案例类型:1-类型1 2-类型2 3-类型3 4-类型4 (IntegerField)
|
||||
选项: [(1, '类型1'), (2, '类型2'), (3, '类型3'), (4, '类型4')]
|
||||
- status: 案例状态:1-正常 2-禁用 (IntegerField)
|
||||
选项: [(1, '正常'), (2, '禁用')]
|
||||
- sort: 排序 (IntegerField)
|
||||
|
||||
==============================================================
|
||||
预览模式 - 不执行代码生成
|
||||
==============================================================
|
||||
```
|
||||
|
||||
## 导出配置
|
||||
|
||||
使用 `--output` 将解析结果导出为 JSON 配置文件:
|
||||
|
||||
```bash
|
||||
# 预览并导出配置
|
||||
python generator.py django_example --dry-run --output config.json
|
||||
|
||||
# 生成代码并同时保存配置
|
||||
python generator.py django_example --output config.json
|
||||
```
|
||||
|
||||
导出的 `config.json` 包含完整的生成配置,可手动编辑后重新使用。
|
||||
|
||||
## 使用配置文件生成
|
||||
|
||||
使用 `--config` 加载已有的 JSON 配置文件,跳过表解析:
|
||||
|
||||
```bash
|
||||
python generator.py --config config.json
|
||||
```
|
||||
|
||||
适用场景:
|
||||
- 需要微调字段配置后重新生成
|
||||
- 表结构已不存在但配置文件保留
|
||||
- 跨项目复用配置
|
||||
|
||||
## 完整参数
|
||||
|
||||
| 参数 | 简写 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `table_name` | - | 数据库表名(位置参数,可选) |
|
||||
| `--config` | `-c` | 使用已有的 JSON 配置文件(跳过表解析) |
|
||||
| `--dry-run` | `-d` | 仅生成配置,不执行代码生成 |
|
||||
| `--output` | `-o` | 将配置导出为 JSON 文件 |
|
||||
|
||||
## 典型工作流
|
||||
|
||||
### 快速生成
|
||||
|
||||
```bash
|
||||
python generator.py django_example
|
||||
```
|
||||
|
||||
### 预览 -> 微调 -> 生成
|
||||
|
||||
```bash
|
||||
# 1. 预览配置
|
||||
python generator.py django_example --dry-run --output config.json
|
||||
|
||||
# 2. 编辑 config.json(调整字段属性、注释等)
|
||||
vim config.json
|
||||
|
||||
# 3. 用配置文件生成
|
||||
python generator.py --config config.json
|
||||
```
|
||||
|
||||
### 仅保存配置
|
||||
|
||||
```bash
|
||||
python generator.py django_example --output config.json
|
||||
```
|
||||
|
||||
## 环境要求
|
||||
|
||||
运行 CLI 前需确保:
|
||||
|
||||
1. **数据库可访问**:CLI 复用 `.env` 中的数据库配置(通过 `config/env.py` 加载),需确保 MySQL 服务正常且连接信息正确
|
||||
2. **Python 依赖已安装**:`pip install -r requirements.txt`(包含 Jinja2、Django 等)
|
||||
3. **表已存在**:目标表需已在数据库中创建完成
|
||||
4. **Django 环境可用**:脚本会自动初始化 Django 环境(`django.setup()`)
|
||||
5. **编码要求**:Windows 环境下确保终端使用 UTF-8 编码(`chcp 65001`)
|
||||
|
||||
:::warning 数据库要求
|
||||
CLI 命令行工具通过查询 MySQL 的 `information_schema` 获取表结构信息,**仅支持 MySQL 数据库**。
|
||||
:::
|
||||
|
||||
## 常见错误
|
||||
|
||||
### 表不存在
|
||||
|
||||
```
|
||||
操作失败: 表 django_xxx 不存在或无业务字段
|
||||
```
|
||||
|
||||
**原因**:数据库中不存在该表,或表名拼写错误。
|
||||
|
||||
**解决**:确认表名正确,且表已在数据库中创建。
|
||||
|
||||
### 数据库连接失败
|
||||
|
||||
```
|
||||
Django环境初始化失败: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server...")
|
||||
```
|
||||
|
||||
**原因**:`.env` 中的数据库配置错误,或 MySQL 服务未启动。
|
||||
|
||||
**解决**:检查 `.env` 中的 `DATABASE_HOST`、`DATABASE_PORT`、`DATABASE_USER`、`DATABASE_PASSWORD` 配置。
|
||||
|
||||
### 编码错误
|
||||
|
||||
```
|
||||
SyntaxError: Non-UTF-8 code start with '\xc8' in file ...
|
||||
```
|
||||
|
||||
**原因**:Windows 终端编码不是 UTF-8。
|
||||
|
||||
**解决**:执行 `chcp 65001` 切换终端编码。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **表名支持带前缀**:`django_example` 和 `example` 都可以,脚本会自动处理 `django_` 前缀(前缀由 `.env` 中的 `DATABASE_PREFIX` 配置)
|
||||
2. **数据库连接**:CLI 复用 `.env` 中的数据库配置,确保数据库可正常访问
|
||||
3. **编码要求**:Windows 环境下确保终端使用 UTF-8 编码(`chcp 65001`)
|
||||
4. **交互模式**:默认为交互模式,会询问是否执行迁移和创建菜单权限;Web 界面调用时使用自动模式(`auto=True`)
|
||||
|
||||
## 总结
|
||||
|
||||
CLI 命令行模式通过 `python generator.py` 启动,支持从数据库表解析生成、从配置文件生成、预览模式和配置导出。生成后自动追加路由、注册应用、创建菜单权限节点。
|
||||
@@ -0,0 +1,211 @@
|
||||
:::tip 本章概要
|
||||
代码生成引擎的工作原理,包括配置解析、模板渲染、文件写入和自动注册的完整流程。
|
||||
:::
|
||||
|
||||
# 代码生成引擎
|
||||
|
||||
`generator_config.py` 中的 `CodeGenerator` 类是代码生成器的执行层,负责接收配置字典、渲染模板、写入文件、自动注册路由和菜单。
|
||||
|
||||
## 核心类:CodeGenerator
|
||||
|
||||
```python
|
||||
from generator_config import CodeGenerator
|
||||
|
||||
generator = CodeGenerator(config)
|
||||
generator.generate() # 交互模式(询问迁移和菜单创建)
|
||||
generator.generate(auto=True) # 自动模式(Web 界面调用)
|
||||
```
|
||||
|
||||
### 构造参数
|
||||
|
||||
| 参数 | 说明 |
|
||||
|:----|:----|
|
||||
| `config` | 配置字典(由 `TableSchemaParser.parse()` 或 JSON 文件提供) |
|
||||
|
||||
构造时自动:
|
||||
- 设置模板目录:`public/templates/`
|
||||
- 设置输出目录:`application/{app_name}/`
|
||||
- 初始化 Jinja2 模板环境(`trim_blocks=True`, `lstrip_blocks=True`)
|
||||
|
||||
## generate() 主方法
|
||||
|
||||
### 执行流程
|
||||
|
||||
```
|
||||
步骤1: 创建输出目录 application/{app_name}/
|
||||
│
|
||||
步骤2: 准备模板上下文 _prepare_context()
|
||||
│ - 处理字段信息、选项、标识
|
||||
│ - 分类字段:form_fields / list_fields / filter_fields
|
||||
│
|
||||
步骤3: 渲染后端模板并写入文件
|
||||
│ - models.py (ORM 模型)
|
||||
│ - forms.py (Django 表单验证)
|
||||
│ - services.py (业务逻辑层)
|
||||
│ - views.py (视图层)
|
||||
│ - urls.py (路由配置)
|
||||
│ - apps.py (应用配置)
|
||||
│ - admin.py (后台管理)
|
||||
│
|
||||
步骤3.5: 创建 __init__.py 和 migrations/__init__.py
|
||||
│
|
||||
步骤3.6: 更新 settings.py 的 INSTALLED_APPS
|
||||
│ - 自动追加 'application.{app_name}'
|
||||
│
|
||||
步骤3.7: 更新 application/urls.py
|
||||
│ - 自动追加路由配置
|
||||
│
|
||||
步骤4: 渲染前端模板并写入文件
|
||||
│ - ui/ 或 ui2/ 目录下的 Vue 组件
|
||||
│ - API 接口文件
|
||||
│
|
||||
步骤5: 数据库迁移(仅交互模式)
|
||||
│ - python manage.py makemigrations
|
||||
│ - python manage.py migrate
|
||||
│
|
||||
步骤6: 创建菜单权限节点
|
||||
- 主菜单节点(type=0)
|
||||
- 8 个权限节点(type=1)
|
||||
```
|
||||
|
||||
### 参数
|
||||
|
||||
| 参数 | 说明 |
|
||||
|:----|:----|
|
||||
| `auto` | 自动模式(True: 跳过交互确认,直接执行迁移和创建菜单) |
|
||||
|
||||
## 模板上下文
|
||||
|
||||
### _prepare_context()
|
||||
|
||||
准备后端模板的渲染上下文:
|
||||
|
||||
| 变量 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `app_name` | str | 模块名(如 `example`) |
|
||||
| `module_comment` | str | 中文名(如 `案例`) |
|
||||
| `module_name` | str | 模块名称(下划线移除) |
|
||||
| `model_class_name` | str | 类名(如 `Example`) |
|
||||
| `model_class_name_camel` | str | 驼峰类名(首字母小写) |
|
||||
| `route_prefix` | str | 路由前缀 |
|
||||
| `permission_prefix` | str | 权限前缀(如 `sys:example`) |
|
||||
| `display_field` | str | 显示字段(如 `name`) |
|
||||
| `has_sort` | bool | 有排序字段 |
|
||||
| `has_status` | bool | 有状态字段 |
|
||||
| `has_unique_code` | bool | 有唯一编码字段 |
|
||||
| `has_image_field` | bool | 有图片字段 |
|
||||
| `has_rich_text_field` | bool | 有富文本字段 |
|
||||
| `fields` | list | 全部字段 |
|
||||
| `form_fields` | list | 表单字段 |
|
||||
| `list_fields` | list | 列表显示字段 |
|
||||
| `filter_fields` | list | 筛选字段 |
|
||||
| `filterable_fields` | list | 可过滤字段 |
|
||||
| `searchable_fields` | list | 可搜索字段 |
|
||||
| `editable_fields` | list | 可编辑字段 |
|
||||
|
||||
### _prepare_vue_context()
|
||||
|
||||
在后端上下文基础上扩展前端专用变量:
|
||||
|
||||
| 变量 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `api_path` | str | API 路径(如 `tool/example`) |
|
||||
| `has_export` | bool | 有导出功能 |
|
||||
| `is_tree_structure` | bool | 是否树形结构 |
|
||||
| `parent_id_field` | str | 父级字段名 |
|
||||
| `has_search_form` | bool | 显示搜索表单 |
|
||||
| `show_selection` | bool | 显示复选框(树形结构) |
|
||||
|
||||
## 文件生成
|
||||
|
||||
### 后端文件
|
||||
|
||||
| 模板 | 输出路径 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `models.py.tpl` | `application/{name}/models.py` | ORM 模型 |
|
||||
| `forms.py.tpl` | `application/{name}/forms.py` | Django 表单验证 |
|
||||
| `services.py.tpl` | `application/{name}/services.py` | 业务逻辑层 |
|
||||
| `views.py.tpl` | `application/{name}/views.py` | 视图层 |
|
||||
| `urls.py.tpl` | `application/{name}/urls.py` | 路由配置 |
|
||||
| `apps.py.tpl` | `application/{name}/apps.py` | 应用配置 |
|
||||
| `admin.py.tpl` | `application/{name}/admin.py` | 后台管理 |
|
||||
|
||||
### 前端文件(普通列表)
|
||||
|
||||
| 模板 | 输出路径 |
|
||||
|:----|:----|
|
||||
| `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` |
|
||||
|
||||
### 前端文件(树状列表)
|
||||
|
||||
当表包含 `parent_id` / `pid` 字段时,自动切换为树形模板:
|
||||
|
||||
| 模板 | 输出路径 |
|
||||
|:----|:----|
|
||||
| `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` |
|
||||
| `ui2/columns.ts.tpl` | `ui/src/views/tool/{name}/columns.ts` |
|
||||
| `ui/api.ts.tpl` | `ui/src/api/tool/{name}.ts` |
|
||||
|
||||
树状列表与普通列表共用 `api.ts.tpl`。
|
||||
|
||||
## 自动注册
|
||||
|
||||
### 应用注册
|
||||
|
||||
`_update_installed_apps()` 在 `application/settings.py` 的 `INSTALLED_APPS` 列表末尾追加:
|
||||
|
||||
```python
|
||||
'application.example', # 案例管理
|
||||
```
|
||||
|
||||
幂等操作:如果已存在,跳过。
|
||||
|
||||
### 路由注册
|
||||
|
||||
`_update_main_urls()` 在 `application/urls.py` 的 `urlpatterns` 列表末尾追加:
|
||||
|
||||
```python
|
||||
# 案例模块路由
|
||||
# 访问地址: /example/
|
||||
path('example/', include('application.example.urls')),
|
||||
```
|
||||
|
||||
路由前缀支持下划线转斜杠:`order_item` -> `order/item/`。
|
||||
|
||||
幂等操作:如果路由已存在,跳过。
|
||||
|
||||
### 菜单创建
|
||||
|
||||
`_create_permission_nodes()` 在数据库中创建:
|
||||
|
||||
1. **主菜单**(type=0):模块入口菜单
|
||||
- name: 模块中文名
|
||||
- path: `/{menu_group}/{module_path}`
|
||||
- component: `/{menu_group}/{module_path}/index`
|
||||
- parent_id: 配置中的 `parent_menu_id`
|
||||
|
||||
2. **权限节点**(type=1)x 8 个:
|
||||
|
||||
| 排序 | 权限名称 | 权限标识 |
|
||||
|:----|:----|:----|
|
||||
| 1 | 查询分页 | `{prefix}:page` |
|
||||
| 5 | 查询列表 | `{prefix}:list` |
|
||||
| 10 | 查询详情 | `{prefix}:detail` |
|
||||
| 15 | 添加 | `{prefix}:add` |
|
||||
| 20 | 更新 | `{prefix}:update` |
|
||||
| 25 | 设置状态 | `{prefix}:status` |
|
||||
| 30 | 删除 | `{prefix}:delete` |
|
||||
| 35 | 批量删除 | `{prefix}:batchDelete` |
|
||||
|
||||
幂等操作:如果主菜单已存在(path + type 匹配),更新信息并删除旧权限节点后重建。
|
||||
|
||||
## 总结
|
||||
|
||||
代码生成引擎根据配置字典,通过 Jinja2 模板渲染生成后端(models/forms/services/views/urls/apps/admin)和前端(index.vue/edit.vue/columns.ts/querySchemas.ts/api.ts)全套代码,生成后自动注册应用、路由和权限。
|
||||
@@ -0,0 +1,341 @@
|
||||
:::tip 本章概要
|
||||
代码生成器 JSON 配置文件的格式说明,包括模块名称、字段属性等配置项的详细解释。
|
||||
:::
|
||||
|
||||
# 配置文件详解
|
||||
|
||||
代码生成器支持通过 JSON 配置文件驱动生成。配置文件可通过 CLI `--output` 导出,也可手动编写,然后用 `--config` 加载生成。
|
||||
|
||||
## 导出配置
|
||||
|
||||
```bash
|
||||
# 从数据库表解析并导出
|
||||
python generator.py django_example --dry-run --output config.json
|
||||
|
||||
# 生成代码的同时保存配置
|
||||
python generator.py django_example --output config.json
|
||||
```
|
||||
|
||||
## 使用配置生成
|
||||
|
||||
```bash
|
||||
python generator.py --config config.json
|
||||
```
|
||||
|
||||
跳过表解析,直接从配置文件读取生成参数。适用于:
|
||||
- 微调字段配置后重新生成
|
||||
- 表结构已不存在但配置保留
|
||||
- 跨项目复用配置
|
||||
|
||||
## 配置文件结构
|
||||
|
||||
```json
|
||||
{
|
||||
"app_name": "example",
|
||||
"module_comment": "案例",
|
||||
"model_name": "example",
|
||||
"model_class_name": "Example",
|
||||
"route_prefix": "example",
|
||||
"business_description": "标识系统中的案例数据",
|
||||
"business_description_detail": "包含案例名称, 案例图片等属性",
|
||||
"permission_prefix": "sys:example",
|
||||
"primary_key": "id",
|
||||
"display_field": "name",
|
||||
"display_field_camel": "name",
|
||||
"table_name": "example",
|
||||
"table_prefix": ["django_"],
|
||||
"remove_prefix": true,
|
||||
"menu_group": "tool",
|
||||
"parent_menu_id": 322,
|
||||
"menu_sort": 5,
|
||||
"has_sort": true,
|
||||
"has_status": true,
|
||||
"has_unique_code": false,
|
||||
"has_export": false,
|
||||
"has_image_field": true,
|
||||
"has_rich_text_field": false,
|
||||
"fields": [...]
|
||||
}
|
||||
```
|
||||
|
||||
## 顶层配置项
|
||||
|
||||
### 基础信息
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `app_name` | str | 是 | 模块名(小写下划线),用于目录名和文件名 |
|
||||
| `module_comment` | str | 是 | 模块中文名,用于注释和菜单名 |
|
||||
| `model_name` | str | 否 | 模型名,默认同 `app_name` |
|
||||
| `model_class_name` | str | 是 | 模型类名(帕斯卡命名) |
|
||||
| `route_prefix` | str | 否 | URL 路由前缀,默认同 `app_name`(下划线转斜杠) |
|
||||
| `business_description` | str | 否 | 业务简要描述 |
|
||||
| `business_description_detail` | str | 否 | 业务详细描述 |
|
||||
|
||||
### 权限和标识
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `permission_prefix` | str | 否 | 权限前缀,默认 `sys:{app_name}` |
|
||||
| `display_field` | str | 否 | 显示字段,默认 `name` |
|
||||
| `display_field_camel` | str | 否 | 显示字段驼峰命名 |
|
||||
| `primary_key` | str | 否 | 主键字段,默认 `id` |
|
||||
|
||||
### 表信息
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `table_name` | str | 否 | 数据库表名(去前缀) |
|
||||
| `table_prefix` | list | 否 | 表前缀列表,如 `["django_"]` |
|
||||
| `remove_prefix` | bool | 否 | 是否移除前缀,默认 `true` |
|
||||
|
||||
### 菜单配置
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `menu_group` | str | 否 | 菜单分组,默认 `tool` |
|
||||
| `parent_menu_id` | int | 否 | 父级菜单 ID |
|
||||
| `menu_sort` | int | 否 | 菜单排序,默认 `5` |
|
||||
|
||||
### 功能标识
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `has_sort` | bool | `false` | 有排序字段 |
|
||||
| `has_status` | bool | `false` | 有状态字段 |
|
||||
| `has_unique_code` | bool | `false` | 有唯一编码字段 |
|
||||
| `has_export` | bool | `false` | 有导出功能 |
|
||||
| `has_image_field` | bool | `false` | 有图片字段 |
|
||||
| `has_rich_text_field` | bool | `false` | 有富文本字段 |
|
||||
|
||||
### 字段列表
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `fields` | list | 是 | 字段配置列表 |
|
||||
|
||||
## 字段配置项
|
||||
|
||||
每个字段对象包含:
|
||||
|
||||
### 基础属性
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `name` | str | 是 | 字段名(snake_case) |
|
||||
| `comment` | str | 否 | 字段注释 |
|
||||
| `purpose` | str | 否 | 字段用途说明 |
|
||||
| `type` | str | 是 | Django 字段类型 |
|
||||
| `type_display` | str | 否 | 类型中文显示 |
|
||||
| `max_length` | int | 否 | 最大长度 |
|
||||
|
||||
### 约束属性
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `nullable` | bool | `false` | 是否可空 |
|
||||
| `required` | bool | `true` | 是否必填(与 nullable 相反) |
|
||||
| `is_unique` | bool | `false` | 是否唯一 |
|
||||
| `db_index` | bool | `false` | 是否有索引 |
|
||||
| `default` | any | `null` | 默认值 |
|
||||
|
||||
### 展示控制
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `in_form` | bool | `true` | 出现在表单中 |
|
||||
| `in_list` | bool | `true` | 出现在列表中 |
|
||||
| `editable` | bool | `true` | 可编辑 |
|
||||
| `filterable` | bool | `false` | 作为查询条件 |
|
||||
| `filter_type` | str | `模糊查询` | 筛选类型(`精确匹配`/`模糊查询`) |
|
||||
| `searchable` | bool | `false` | 可搜索 |
|
||||
|
||||
### 功能标识
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|:----|:----|:----|:----|
|
||||
| `is_image` | bool | `false` | 图片字段 |
|
||||
| `is_rich_text` | bool | `false` | 富文本字段 |
|
||||
|
||||
### 选项属性
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `choices` | list | `[[value, label], ...]` 元组列表 |
|
||||
| `min_value` | int | 最小值 |
|
||||
| `max_value` | int | 最大值 |
|
||||
|
||||
## 完整示例
|
||||
|
||||
```json
|
||||
{
|
||||
"app_name": "example",
|
||||
"module_comment": "案例",
|
||||
"model_name": "example",
|
||||
"model_class_name": "Example",
|
||||
"route_prefix": "example",
|
||||
"business_description": "标识系统中的案例数据",
|
||||
"business_description_detail": "包含案例名称, 案例图片, 案例类型等属性",
|
||||
"permission_prefix": "sys:example",
|
||||
"primary_key": "id",
|
||||
"display_field": "name",
|
||||
"display_field_camel": "name",
|
||||
"table_name": "example",
|
||||
"table_prefix": ["django_"],
|
||||
"remove_prefix": true,
|
||||
"menu_group": "tool",
|
||||
"parent_menu_id": 322,
|
||||
"menu_sort": 5,
|
||||
"has_sort": true,
|
||||
"has_status": true,
|
||||
"has_unique_code": false,
|
||||
"has_export": false,
|
||||
"has_image_field": true,
|
||||
"has_rich_text_field": false,
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"comment": "案例名称",
|
||||
"purpose": "存储案例名称信息",
|
||||
"type": "CharField",
|
||||
"type_display": "字符串",
|
||||
"max_length": 100,
|
||||
"nullable": false,
|
||||
"required": true,
|
||||
"is_unique": false,
|
||||
"db_index": true,
|
||||
"default": null,
|
||||
"in_form": true,
|
||||
"in_list": true,
|
||||
"filterable": true,
|
||||
"filter_type": "模糊查询",
|
||||
"editable": true,
|
||||
"searchable": true,
|
||||
"is_image": false,
|
||||
"is_rich_text": false
|
||||
},
|
||||
{
|
||||
"name": "avatar",
|
||||
"comment": "案例图片",
|
||||
"purpose": "存储案例图片信息",
|
||||
"type": "CharField",
|
||||
"type_display": "字符串",
|
||||
"max_length": 255,
|
||||
"nullable": true,
|
||||
"required": false,
|
||||
"in_form": true,
|
||||
"in_list": true,
|
||||
"filterable": false,
|
||||
"is_image": true,
|
||||
"is_rich_text": false
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"comment": "案例类型:1-类型1 2-类型2 3-类型3 4-类型4",
|
||||
"type": "IntegerField",
|
||||
"type_display": "整数",
|
||||
"nullable": false,
|
||||
"required": true,
|
||||
"in_form": true,
|
||||
"in_list": true,
|
||||
"filterable": true,
|
||||
"filter_type": "精确匹配",
|
||||
"choices": [[1, "类型1"], [2, "类型2"], [3, "类型3"], [4, "类型4"]],
|
||||
"min_value": 1,
|
||||
"max_value": 4
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"comment": "案例状态:1-正常 2-禁用",
|
||||
"type": "IntegerField",
|
||||
"type_display": "整数",
|
||||
"nullable": false,
|
||||
"required": true,
|
||||
"in_form": true,
|
||||
"in_list": true,
|
||||
"filterable": true,
|
||||
"filter_type": "精确匹配",
|
||||
"choices": [[1, "正常"], [2, "禁用"]],
|
||||
"min_value": 1,
|
||||
"max_value": 2
|
||||
},
|
||||
{
|
||||
"name": "sort",
|
||||
"comment": "排序",
|
||||
"type": "IntegerField",
|
||||
"type_display": "整数",
|
||||
"nullable": false,
|
||||
"required": true,
|
||||
"in_form": true,
|
||||
"in_list": true,
|
||||
"filterable": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 字段类型映射
|
||||
|
||||
`type` 必须是以下值之一:
|
||||
|
||||
| 合法值 | 对应 Django 模型字段 |
|
||||
|:----|:----|
|
||||
| `CharField` | CharField(需配合 `max_length`) |
|
||||
| `TextField` | TextField |
|
||||
| `IntegerField` | IntegerField |
|
||||
| `DateTimeField` | DateTimeField |
|
||||
| `DateField` | DateField |
|
||||
| `FloatField` | FloatField |
|
||||
| `DecimalField` | DecimalField |
|
||||
| `BooleanField` | BooleanField |
|
||||
|
||||
`filter_type` 必须是以下值之一:`精确匹配` / `模糊查询`
|
||||
|
||||
## 常用微调场景
|
||||
|
||||
### 修改模块中文名
|
||||
|
||||
```json
|
||||
{
|
||||
"module_comment": "培训记录"
|
||||
}
|
||||
```
|
||||
|
||||
### 隐藏字段(不出现在列表/表单)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "internal_code",
|
||||
"in_form": false,
|
||||
"in_list": false
|
||||
}
|
||||
```
|
||||
|
||||
### 添加自定义字段
|
||||
|
||||
在 `fields` 数组中追加新的字段配置。
|
||||
|
||||
### 修改筛选类型
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "name",
|
||||
"filterable": true,
|
||||
"filter_type": "精确匹配"
|
||||
}
|
||||
```
|
||||
|
||||
### 添加选项
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "level",
|
||||
"choices": [[1, "初级"], [2, "中级"], [3, "高级"]],
|
||||
"min_value": 1,
|
||||
"max_value": 3
|
||||
}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
配置文件为 JSON 格式,包含模块名称、表名、字段属性等信息。支持字段级别的精细配置(是否可搜索、是否在列表显示等),可通过 CLI 导出或手动编写。
|
||||
@@ -0,0 +1,321 @@
|
||||
:::tip 本章概要
|
||||
以 `django_example` 演示表为完整案例,演示从建表到生成到使用的全流程。
|
||||
:::
|
||||
|
||||
# 实战案例
|
||||
|
||||
以 `django_example` 演示表为完整案例,演示从建表到生成到使用的全流程。该表对应项目中的 `application/example/` 模块。
|
||||
|
||||
## 第 1 步:创建数据表
|
||||
|
||||
在数据库中执行建表语句:
|
||||
|
||||
```sql
|
||||
CREATE TABLE `django_example` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL COMMENT '案例名称',
|
||||
`avatar` varchar(255) DEFAULT NULL COMMENT '案例图片',
|
||||
`type` int DEFAULT 1 COMMENT '案例类型:1-类型1 2-类型2 3-类型3 4-类型4',
|
||||
`status` int DEFAULT 1 COMMENT '案例状态:1-正常 2-禁用',
|
||||
`sort` int DEFAULT 0 COMMENT '排序',
|
||||
`create_user` varchar(50) DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_user` varchar(50) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`is_delete` int DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_name` (`name`)
|
||||
) COMMENT='案例表';
|
||||
```
|
||||
|
||||
## 第 2 步:预览配置
|
||||
|
||||
```bash
|
||||
python generator.py django_example --dry-run
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
==============================================================
|
||||
数据库表结构解析和代码生成工具
|
||||
==============================================================
|
||||
正在解析表: django_example
|
||||
表结构解析成功
|
||||
|
||||
------------------------------------------------------------
|
||||
生成配置摘要:
|
||||
------------------------------------------------------------
|
||||
应用名称: example
|
||||
模块名称: 案例
|
||||
模型类名: Example
|
||||
字段数量: 5
|
||||
是否有排序: True
|
||||
是否有状态: True
|
||||
是否有图片: True
|
||||
是否有富文本: False
|
||||
|
||||
字段列表:
|
||||
- name: 案例名称 (CharField)
|
||||
- avatar: 案例图片 (CharField)
|
||||
- type: 案例类型:1-类型1 2-类型2 3-类型3 4-类型4 (IntegerField)
|
||||
选项: [(1, '类型1'), (2, '类型2'), (3, '类型3'), (4, '类型4')]
|
||||
- status: 案例状态:1-正常 2-禁用 (IntegerField)
|
||||
选项: [(1, '正常'), (2, '禁用')]
|
||||
- sort: 排序 (IntegerField)
|
||||
|
||||
==============================================================
|
||||
预览模式 - 不执行代码生成
|
||||
==============================================================
|
||||
```
|
||||
|
||||
## 第 3 步:生成代码
|
||||
|
||||
```bash
|
||||
python generator.py django_example
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
==============================================================
|
||||
数据库表结构解析和代码生成工具
|
||||
==============================================================
|
||||
正在解析表: django_example
|
||||
表结构解析成功
|
||||
...
|
||||
创建输出目录: application/example
|
||||
生成文件: application/example/models.py
|
||||
生成文件: application/example/forms.py
|
||||
生成文件: application/example/services.py
|
||||
生成文件: application/example/views.py
|
||||
生成文件: application/example/urls.py
|
||||
生成文件: application/example/apps.py
|
||||
生成文件: application/example/admin.py
|
||||
生成文件: ui/src/views/tool/example/index.vue
|
||||
生成文件: ui/src/views/tool/example/edit.vue
|
||||
生成文件: ui/src/views/tool/example/detail.vue
|
||||
生成文件: ui/src/views/tool/example/querySchemas.ts
|
||||
生成文件: ui/src/views/tool/example/columns.ts
|
||||
生成文件: ui/src/api/tool/example.ts
|
||||
已添加应用: application.example
|
||||
已添加路由: path('example/', include('application.example.urls'))
|
||||
主菜单创建成功,ID: xxx
|
||||
创建权限节点: 查询案例分页
|
||||
创建权限节点: 查询案例列表
|
||||
...
|
||||
菜单权限节点创建完成!共创建 8 个权限节点
|
||||
代码生成完成!
|
||||
```
|
||||
|
||||
## 第 4 步:验证生成结果
|
||||
|
||||
### 检查后端文件
|
||||
|
||||
```bash
|
||||
ls application/example/
|
||||
# __init__.py models.py forms.py services.py views.py urls.py apps.py admin.py migrations/
|
||||
```
|
||||
|
||||
### 检查前端文件
|
||||
|
||||
```bash
|
||||
ls ui/src/views/tool/example/
|
||||
# index.vue edit.vue detail.vue columns.ts querySchemas.ts
|
||||
|
||||
ls ui/src/api/tool/example.ts
|
||||
# example.ts
|
||||
```
|
||||
|
||||
### 检查路由注册
|
||||
|
||||
在 `application/urls.py` 中应新增:
|
||||
|
||||
```python
|
||||
# 案例模块路由
|
||||
path('example/', include('application.example.urls')),
|
||||
```
|
||||
|
||||
### 检查应用注册
|
||||
|
||||
在 `application/settings.py` 的 `INSTALLED_APPS` 中应新增:
|
||||
|
||||
```python
|
||||
'application.example', # 案例管理
|
||||
```
|
||||
|
||||
## 第 5 步:重启后端
|
||||
|
||||
```bash
|
||||
python manage.py runserver
|
||||
```
|
||||
|
||||
## 第 6 步:访问页面
|
||||
|
||||
1. 登录管理后台
|
||||
2. 左侧菜单找到「开发工具 -> 案例」
|
||||
3. 进入案例管理页面,测试增删改查功能
|
||||
|
||||
## 生成代码逐文件解析
|
||||
|
||||
### models.py
|
||||
|
||||
```python
|
||||
class Example(BaseModel):
|
||||
name = models.CharField(
|
||||
null=False, max_length=100, db_index=True,
|
||||
verbose_name="案例名称", db_comment='案例名称'
|
||||
)
|
||||
avatar = models.CharField(
|
||||
null=True, blank=True, max_length=255,
|
||||
verbose_name="案例图片", db_comment='案例图片'
|
||||
)
|
||||
TYPE_CHOICES = ((1, "类型1"), (2, "类型2"), (3, "类型3"), (4, "类型4"))
|
||||
type = models.IntegerField(
|
||||
null=False, choices=TYPE_CHOICES,
|
||||
verbose_name="案例类型:1-类型1 2-类型2 3-类型3 4-类型4",
|
||||
db_comment='案例类型:1-类型1 2-类型2 3-类型3 4-类型4'
|
||||
)
|
||||
STATUS_CHOICES = ((1, "正常"), (2, "禁用"))
|
||||
status = models.IntegerField(
|
||||
null=False, choices=STATUS_CHOICES,
|
||||
verbose_name="案例状态:1-正常 2-禁用",
|
||||
db_comment='案例状态:1-正常 2-禁用'
|
||||
)
|
||||
sort = models.IntegerField(null=False, verbose_name="排序", db_comment='排序')
|
||||
|
||||
class Meta:
|
||||
db_table = get_table_name('example')
|
||||
db_table_comment = "案例表"
|
||||
ordering = ("sort",)
|
||||
```
|
||||
|
||||
- 继承 `BaseModel`,自动拥有 id/create_user/create_time/update_user/update_time/is_delete 字段
|
||||
- 自动映射字段类型(varchar->CharField, int->IntegerField)
|
||||
- 自动识别 `avatar` 为图片字段
|
||||
- 自动解析注释中的选项生成 `TYPE_CHOICES` 和 `STATUS_CHOICES`
|
||||
- `db_comment` 参数用于 Django 4.1+ 自动添加数据库字段注释
|
||||
|
||||
### forms.py
|
||||
|
||||
```python
|
||||
class ExampleForm(forms.ModelForm):
|
||||
name = forms.CharField(
|
||||
required=True, max_length=100,
|
||||
error_messages={'required': '案例名称不能为空', 'max_length': '案例名称长度不得超过100个字符'}
|
||||
)
|
||||
avatar = forms.CharField(required=False, max_length=255)
|
||||
type = forms.IntegerField(
|
||||
required=True, min_value=1, max_value=4,
|
||||
error_messages={'required': '案例类型不能为空'}
|
||||
)
|
||||
status = forms.IntegerField(
|
||||
required=True, min_value=1, max_value=2,
|
||||
error_messages={'required': '案例状态不能为空'}
|
||||
)
|
||||
sort = forms.IntegerField(required=True)
|
||||
|
||||
class Meta:
|
||||
model = models.Example
|
||||
fields = ['name', 'avatar', 'type', 'status', 'sort']
|
||||
```
|
||||
|
||||
- 继承 `forms.ModelForm`,自动绑定模型
|
||||
- 中文 `error_messages` 提供友好的验证提示
|
||||
- `min_value`/`max_value` 限制取值范围
|
||||
|
||||
### services.py
|
||||
|
||||
```python
|
||||
def get_example_page(request):
|
||||
page_no = int(request.GET.get('pageNo', 1))
|
||||
page_size = int(request.GET.get('pageSize', PAGE_SIZE))
|
||||
query = Example.objects.filter(is_delete=False)
|
||||
query = _apply_filters(query, request)
|
||||
query = query.order_by("sort")
|
||||
paginator = Paginator(query, page_size)
|
||||
page_list = paginator.page(page_no)
|
||||
return R.ok(data=_build_page_data(page_list, paginator, page_no, page_size))
|
||||
|
||||
def add_example(request):
|
||||
data, error = parse_request_body(request)
|
||||
form = forms.ExampleForm(data)
|
||||
if not form.is_valid():
|
||||
return R.failed(msg=regular.get_err(form))
|
||||
Example.objects.create(...)
|
||||
return R.ok(msg="创建成功")
|
||||
```
|
||||
|
||||
- 所有查询过滤 `is_delete=False`
|
||||
- 使用 Django `Paginator` 分页
|
||||
- `parse_request_body` 解析请求体
|
||||
- 表单验证在 ORM 操作之前
|
||||
|
||||
### views.py
|
||||
|
||||
```python
|
||||
@method_decorator(check_login, name="get")
|
||||
class ExamplePageView(PermissionRequired, View):
|
||||
permission_required = ("sys:example:page",)
|
||||
|
||||
@operation_log(title="案例管理-查询分页列表", log_type=LogType.QUERY)
|
||||
def get(self, request):
|
||||
return services.get_example_page(request)
|
||||
|
||||
@method_decorator(check_login, name="post")
|
||||
class ExampleAddView(PermissionRequired, View):
|
||||
permission_required = ("sys:example:add",)
|
||||
|
||||
@operation_log(title="案例管理-添加记录", log_type=LogType.ADD)
|
||||
def post(self, request):
|
||||
if DJANGO_DEMO:
|
||||
return R.failed("演示环境,暂无操作权限")
|
||||
return services.add_example(request)
|
||||
```
|
||||
|
||||
- `@method_decorator(check_login)` 验证 JWT 登录
|
||||
- `PermissionRequired` 检查权限节点
|
||||
- `@operation_log` 记录操作日志
|
||||
- 写操作检查 `DJANGO_DEMO` 演示模式
|
||||
|
||||
## 树状表示例
|
||||
|
||||
当表中包含 `parent_id` 或 `pid` 字段时,生成器自动切换为树状模板。
|
||||
|
||||
```sql
|
||||
CREATE TABLE `django_category` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL COMMENT '分类名称',
|
||||
`parent_id` int DEFAULT 0 COMMENT '父级ID(0为顶级)',
|
||||
`sort` int DEFAULT 0 COMMENT '排序',
|
||||
`status` int DEFAULT 1 COMMENT '状态:1-正常 2-禁用',
|
||||
`create_user` varchar(50) DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_user` varchar(50) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`is_delete` int DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT='分类表';
|
||||
```
|
||||
|
||||
生成器自动:
|
||||
1. **前端模板切换**:使用 `ui2/` 树形模板替代 `ui/` 普通列表模板
|
||||
2. **数据加载方式**:全量加载 + 前端 `buildTree` 构建树形结构
|
||||
|
||||
## 生成后的自定义
|
||||
|
||||
代码生成后,通常需要根据业务需求进行微调:
|
||||
|
||||
| 自定义项 | 涉及文件 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| 添加业务校验 | `forms.py` | 添加自定义验证方法 `clean_xxx` |
|
||||
| 添加删除前检查 | `services.py` | 在 `delete_xxx` 中检查关联数据 |
|
||||
| 添加创建前处理 | `services.py` | 在 `add_xxx` 中处理特殊字段(如密码哈希) |
|
||||
| 修改序列化 | `services.py` | 修改 `_build_page_data` 中的字段映射 |
|
||||
| 添加自定义接口 | `views.py` + `urls.py` | 新增视图类和路由 |
|
||||
| 调整前端布局 | `index.vue` | 修改表格列宽、操作按钮等 |
|
||||
| 调整表单校验 | `edit.vue` | 修改表单规则、默认值等 |
|
||||
|
||||
## 总结
|
||||
|
||||
通过以上 6 步即可完成一个完整业务模块的生成:建表 -> 预览 -> 生成 -> 验证 -> 重启 -> 使用。整个过程约 1 分钟,生成约 12 个文件,涵盖后端 MVC + 前端页面 + 路由注册 + 菜单权限。生成后根据业务需求进行微调即可投入使用。
|
||||
@@ -0,0 +1,146 @@
|
||||
:::tip 本章概要
|
||||
代码生成器使用过程中常见问题的原因分析和解决方案。
|
||||
:::
|
||||
|
||||
# 常见问题
|
||||
|
||||
## 生成后前端页面不显示
|
||||
|
||||
**排查步骤**:
|
||||
|
||||
1. **确认菜单已创建**:检查数据库 `django_menu` 表中是否有对应路径的记录
|
||||
2. **确认路由组件路径**:菜单的 `component` 字段应为 `/tool/example/index`
|
||||
3. **确认权限已分配**:当前用户需要有对应菜单的访问权限(超级管理员 ID=1 自动拥有所有权限)
|
||||
4. **清除缓存**:退出重新登录,或清除浏览器缓存
|
||||
5. **确认后端已重启**:新路由需要重启后端服务才能生效
|
||||
|
||||
## 如何重新生成?
|
||||
|
||||
完整清理流程:
|
||||
|
||||
```bash
|
||||
# 1. 删除后端模块
|
||||
rm -rf application/example
|
||||
|
||||
# 2. 清理 application/urls.py 中的路由配置
|
||||
# 删除 path('example/', include('application.example.urls')),
|
||||
|
||||
# 3. 清理 application/settings.py 中的应用注册
|
||||
# 删除 'application.example',
|
||||
|
||||
# 4. 删除前端文件
|
||||
rm -rf ui/src/views/tool/example
|
||||
rm ui/src/api/tool/example.ts
|
||||
|
||||
# 5. 删除数据库菜单
|
||||
# DELETE FROM django_menu WHERE path = '/tool/example';
|
||||
|
||||
# 6. 重新生成
|
||||
python generator.py django_example
|
||||
```
|
||||
|
||||
## 批量生成有数量限制吗?
|
||||
|
||||
Web API 批量生成最多支持 50 个表。CLI 无限制,但建议逐表生成,便于排查问题。
|
||||
|
||||
## 树状列表是如何判断的?
|
||||
|
||||
当表中存在 `parent_id` 或 `pid` 字段时,自动切换为树状模板(`ui2/`),生成树形结构的增删改查页面。
|
||||
|
||||
树状列表与普通分页列表的区别:
|
||||
|
||||
| 维度 | 普通列表(ui/) | 树状列表(ui2/) |
|
||||
|:----|:----|:----|
|
||||
| 触发条件 | 无 parent_id/pid | 有 parent_id/pid |
|
||||
| 模板数量 | 5 个组件 + 1 个 API | 4 个组件 + 1 个 API |
|
||||
| 数据加载 | 分页请求 | 全量加载 + 前端 buildTree |
|
||||
| 展开/折叠 | 无 | 支持 |
|
||||
|
||||
## CLI 报错 "No module named 'application'"
|
||||
|
||||
**原因**:未在项目根目录执行命令。
|
||||
|
||||
**解决**:确保在项目根目录(包含 `manage.py` 和 `generator.py` 的目录)执行:
|
||||
|
||||
```bash
|
||||
cd /data/apps/DjangoAdmin_Django_EleVue
|
||||
python generator.py django_example
|
||||
```
|
||||
|
||||
## CLI 报错 "Django环境初始化失败"
|
||||
|
||||
**原因**:Django 环境未正确配置。
|
||||
|
||||
**解决**:
|
||||
1. 确保已激活虚拟环境
|
||||
2. 确保已安装所有依赖:`pip install -r requirements.txt`
|
||||
3. 确保 `application/settings.py` 文件存在
|
||||
4. 确保 MySQL 和 Redis 服务正常运行
|
||||
|
||||
## 生成的代码有语法错误
|
||||
|
||||
**可能原因**:
|
||||
- 表名或字段名包含特殊字符
|
||||
- 字段注释包含未转义的引号
|
||||
- 数据库连接异常导致解析不完整
|
||||
|
||||
**解决**:
|
||||
1. 使用 `--dry-run` 检查解析结果
|
||||
2. 导出配置文件检查字段内容:`python generator.py django_example --dry-run --output config.json`
|
||||
3. 手动修正配置文件后用 `--config` 重新生成
|
||||
|
||||
## 如何自定义生成的代码风格?
|
||||
|
||||
修改 `public/templates/` 下的模板文件。模板使用 Jinja2 语法,详见 [6.6 自定义模板](/zh/volume5/templates)。
|
||||
|
||||
修改模板后重新生成即可生效,不影响已有模块。
|
||||
|
||||
## 生成速度慢
|
||||
|
||||
**可能原因**:
|
||||
- 数据库连接延迟高
|
||||
- 表字段数量非常多(50+ 字段)
|
||||
- 同时生成大量表(批量生成)
|
||||
|
||||
**解决**:
|
||||
- 检查数据库网络连接
|
||||
- 减少单次批量生成的表数量
|
||||
- 使用 CLI 单表生成替代批量生成
|
||||
|
||||
## 生成器支持哪些数据库?
|
||||
|
||||
:::warning 数据库限制
|
||||
代码生成器通过查询 MySQL 的 `information_schema` 获取表结构信息,**仅支持 MySQL 数据库**。
|
||||
:::
|
||||
|
||||
## 模板语法错误如何排查?
|
||||
|
||||
**症状**:生成时报错 `jinja2.exceptions.TemplateSyntaxError`。
|
||||
|
||||
**排查步骤**:
|
||||
1. 查看错误信息中的模板文件名和行号
|
||||
2. 打开对应的 `.tpl` 文件检查语法
|
||||
3. 常见错误:
|
||||
- `{% if %}` 缺少 `{% endif %}`
|
||||
- 变量名拼写错误(如 `f.nmae` 应为 `f.name`)
|
||||
- 使用了未定义的变量
|
||||
4. 修改模板后重新生成
|
||||
|
||||
## 字段识别不准确
|
||||
|
||||
**可能原因**:
|
||||
- 字段注释格式不符合解析规则
|
||||
- 字段名不在自动识别的关键词列表中
|
||||
|
||||
**解决**:
|
||||
1. 导出配置文件:`python generator.py django_example --dry-run --output config.json`
|
||||
2. 手动修改配置文件中的字段属性
|
||||
3. 用配置文件重新生成:`python generator.py --config config.json`
|
||||
|
||||
## 总结
|
||||
|
||||
大部分问题可通过以下流程解决:
|
||||
1. 使用 `--dry-run` 预览配置
|
||||
2. 清理旧文件后重新生成
|
||||
3. 确认数据库菜单和权限配置正确
|
||||
4. 重启后端服务
|
||||
@@ -0,0 +1,137 @@
|
||||
:::tip 本章概要
|
||||
代码生成器的整体架构、核心模块和生成流程概述。
|
||||
:::
|
||||
|
||||
# 概述与架构
|
||||
|
||||
代码生成器是项目的核心效率工具,能够根据数据库表结构自动生成完整的后端 Django 模块代码和前端 Vue 页面代码,并自动注册路由和菜单权限节点。
|
||||
|
||||
## 生成能力总览
|
||||
|
||||
| 维度 | 生成内容 |
|
||||
|:----|:----|
|
||||
| 后端模块 | `__init__.py` / `models.py` / `forms.py` / `services.py` / `views.py` / `urls.py` / `apps.py` / `admin.py` |
|
||||
| 后端路由 | 自动追加到 `application/urls.py` + 注册到 `INSTALLED_APPS` |
|
||||
| 前端页面 | `index.vue` / `edit.vue` / `detail.vue` / `columns.ts` / `querySchemas.ts` / `api.ts` |
|
||||
| 菜单权限 | 自动创建菜单节点 + 8 个权限节点 |
|
||||
|
||||
## 两种使用方式
|
||||
|
||||
| 方式 | 入口 | 适用场景 |
|
||||
|:----|:----|:----|
|
||||
| CLI 命令行 | `python generator.py <表名>` | 开发阶段,快速生成单个模块 |
|
||||
| Web 管理界面 | 开发工具 -> 代码生成 | 运维阶段,可视化操作,支持批量生成 |
|
||||
|
||||
两种方式共享同一套引擎代码,生成结果完全一致。
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
项目根目录
|
||||
├── generator.py # CLI 命令行入口(含 TableSchemaParser)
|
||||
├── generator_config.py # 代码生成引擎(CodeGenerator)
|
||||
├── config.json # 示例配置文件
|
||||
└── public/templates/ # Jinja2 模板目录
|
||||
├── models.py.tpl # ORM 模型
|
||||
├── forms.py.tpl # Django 表单验证
|
||||
├── services.py.tpl # 业务逻辑层
|
||||
├── views.py.tpl # 视图层
|
||||
├── urls.py.tpl # 路由配置
|
||||
├── apps.py.tpl # 应用配置
|
||||
├── admin.py.tpl # 后台管理
|
||||
├── ui/ # 普通分页列表模板
|
||||
│ ├── index.vue.tpl
|
||||
│ ├── edit.vue.tpl
|
||||
│ ├── detail.vue.tpl
|
||||
│ ├── columns.ts.tpl
|
||||
│ ├── querySchemas.ts.tpl
|
||||
│ └── api.ts.tpl
|
||||
└── ui2/ # 树状列表模板
|
||||
├── index.vue.tpl
|
||||
├── edit.vue.tpl
|
||||
├── detail.vue.tpl
|
||||
└── columns.ts.tpl
|
||||
```
|
||||
|
||||
## 核心组件
|
||||
|
||||
### generator.py -- 表结构解析器
|
||||
|
||||
包含 `TableSchemaParser` 类,从 `information_schema` 读取表元数据,输出标准化配置字典。智能识别图片字段、富文本字段、状态字段、排序字段、枚举字段、查询条件等。同时作为 CLI 入口,提供命令行参数解析。
|
||||
|
||||
### generator_config.py -- 代码生成引擎
|
||||
|
||||
包含 `CodeGenerator` 类,接收配置字典,通过 Jinja2 渲染模板,写入文件,并自动追加路由到 `application/urls.py`、注册应用到 `settings.py` 的 `INSTALLED_APPS`、创建菜单权限节点。
|
||||
|
||||
### application/generator/ -- Web API 业务逻辑
|
||||
|
||||
提供表分页查询、表详情、字段查询、单表/批量生成等服务方法,供 HTTP 端点调用。底层调用 `generator.py` 和 `generator_config.py` 的功能。
|
||||
|
||||
### public/templates/ -- 模板目录
|
||||
|
||||
Jinja2 模板文件,分为后端模板(7 个)和前端模板(ui/ 6 个 + ui2/ 4 个)。含 `parent_id` / `pid` 字段的表自动切换为树形模板(ui2/)。
|
||||
|
||||
## 生成流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ 数据库 information_schema │
|
||||
└──────────────────┬──────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ generator.py(TableSchemaParser) │
|
||||
│ - 智能识别字段类型/图片/富文本/状态 │
|
||||
│ - 生成标准化配置字典 │
|
||||
└──────────────────┬──────────────────┘
|
||||
│ 配置字典
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ generator_config.py(CodeGenerator) │
|
||||
│ - Jinja2 模板渲染 │
|
||||
│ - 写入文件 │
|
||||
└───┬──────────┬──────────┬──────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────────┐
|
||||
│ 后端模块 │ │ 前端页面 │ │ 自动注册 │
|
||||
│ models │ │ index.vue│ │ urls.py │
|
||||
│ forms │ │ edit.vue │ │ settings.py │
|
||||
│ services │ │ columns │ │ 菜单权限节点 │
|
||||
│ views │ │ api.ts │ │ │
|
||||
│ urls │ │ ... │ │ │
|
||||
└──────────┘ └──────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
## 使用限制
|
||||
|
||||
:::warning 使用前提
|
||||
1. **数据库要求**:代码生成器基于 MySQL 的 `information_schema` 查询表结构,仅支持 MySQL 数据库。
|
||||
2. **表结构要求**:不支持复合主键、外键关联等复杂表结构,建议使用单主键(自增 id)的标准业务表。
|
||||
3. **环境要求**:需确保 Django 环境已初始化、MySQL 和 Redis 服务正常运行。
|
||||
:::
|
||||
|
||||
## 演示表
|
||||
|
||||
本章以 `django_example` 表为贯穿案例,对应 `application/example/` 模块:
|
||||
|
||||
```sql
|
||||
CREATE TABLE `django_example` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL COMMENT '案例名称',
|
||||
`avatar` varchar(255) DEFAULT NULL COMMENT '案例图片',
|
||||
`type` int DEFAULT 1 COMMENT '案例类型:1-类型1 2-类型2 3-类型3 4-类型4',
|
||||
`status` int DEFAULT 1 COMMENT '案例状态:1-正常 2-禁用',
|
||||
`sort` int DEFAULT 0 COMMENT '排序',
|
||||
`create_user` varchar(50) DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_user` varchar(50) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`is_delete` int DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT='案例表';
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
代码生成器通过解析数据库表结构,自动生成符合项目规范的完整模块代码。CLI 适合开发阶段快速生成,Web 界面适合运维阶段批量管理。模板使用 Jinja2 语法,可自由定制生成结果。
|
||||
@@ -0,0 +1,228 @@
|
||||
:::tip 本章概要
|
||||
表结构解析引擎的工作原理,从数据库读取表元数据并智能推断字段用途的过程。
|
||||
:::
|
||||
|
||||
# 表结构解析引擎
|
||||
|
||||
`generator.py` 中的 `TableSchemaParser` 类是代码生成器的解析层,负责从数据库 `information_schema` 读取表元数据,输出标准化的配置字典。
|
||||
|
||||
## 核心类:TableSchemaParser
|
||||
|
||||
```python
|
||||
from generator import TableSchemaParser
|
||||
|
||||
parser = TableSchemaParser("django_example")
|
||||
config = parser.parse()
|
||||
```
|
||||
|
||||
### 构造参数
|
||||
|
||||
| 参数 | 说明 |
|
||||
|:----|:----|
|
||||
| `table_name` | 数据库表名,可带前缀(`django_example`)或不带前缀(`example`) |
|
||||
|
||||
构造时自动处理:
|
||||
- 保存原始表名(用于数据库查询)
|
||||
- 去掉 `django_` 前缀(前缀由 `config/env.py` 中的 `DATABASE_PREFIX` 配置)
|
||||
- 初始化排除字段列表(`id` / `create_user` / `create_time` / `update_user` / `update_time` / `is_delete`)
|
||||
|
||||
## 解析流程
|
||||
|
||||
`parse()` 方法执行 9 步:
|
||||
|
||||
```
|
||||
1. 获取表信息(TABLE_COMMENT、ENGINE 等)
|
||||
2. 获取字段列表(排除系统字段)
|
||||
3. 获取索引信息
|
||||
4. 清理表名(去掉 sys_/tb_/django_/auth_/captcha_ 前缀)
|
||||
5. 构建命名(app_name / module_comment / model_class_name / route_prefix)
|
||||
6. 构建字段配置列表
|
||||
7. 判断功能标识(has_sort / has_status / has_unique_code)
|
||||
8. 获取显示字段(优先 name -> title -> 第一个字符串字段)
|
||||
9. 组装完整配置字典
|
||||
```
|
||||
|
||||
## 智能识别规则
|
||||
|
||||
### 图片字段
|
||||
|
||||
字段名包含以下关键词时,`is_image` 标记为 `True`:
|
||||
|
||||
```
|
||||
avatar / cover / logo / image / photo / picture / img / icon / thumbnail / banner
|
||||
```
|
||||
|
||||
效果:
|
||||
- 前端表单生成图片上传组件
|
||||
- 列表中显示图片预览
|
||||
- Service 层自动处理文件保存和 URL 补全
|
||||
- 自动设置 `filterable=False`、`searchable=False`
|
||||
|
||||
### 富文本字段
|
||||
|
||||
`TextField` 类型字段且注释包含以下关键词时,`is_rich_text` 标记为 `True`:
|
||||
|
||||
```
|
||||
内容 / 介绍 / 说明 / 描述 / 详情 / 正文
|
||||
```
|
||||
|
||||
效果:
|
||||
- 前端表单生成富文本编辑器
|
||||
|
||||
### 状态字段
|
||||
|
||||
字段名包含以下关键词时,识别为状态字段:
|
||||
|
||||
```
|
||||
status / state / is_active / is_enabled / is_deleted
|
||||
```
|
||||
|
||||
效果:
|
||||
- 自动生成状态切换接口(`/status`)
|
||||
- 前端列表生成状态标签(启用/停用)
|
||||
- `has_status=True`
|
||||
|
||||
### 排序字段
|
||||
|
||||
字段名包含以下关键词时,识别为排序字段:
|
||||
|
||||
```
|
||||
sort / order / seq / sequence / priority
|
||||
```
|
||||
|
||||
效果:
|
||||
- 分页查询默认按此字段排序
|
||||
- `has_sort=True`
|
||||
|
||||
### 枚举字段
|
||||
|
||||
字段注释包含 `数字-文本` 格式(如 `1-正常 2-停用`)时,自动解析为选项列表:
|
||||
|
||||
```python
|
||||
# 注释:"案例类型:1-类型1 2-类型2 3-类型3 4-类型4"
|
||||
# 解析结果:
|
||||
choices = [(1, '类型1'), (2, '类型2'), (3, '类型3'), (4, '类型4')]
|
||||
min_value = 1
|
||||
max_value = 4
|
||||
```
|
||||
|
||||
效果:
|
||||
- 前端表单生成下拉选择框
|
||||
- 列表中显示选项文本而非数字
|
||||
- 自动设置 `filter_type='精确匹配'`
|
||||
|
||||
### 查询条件
|
||||
|
||||
字段满足以下任一条件时,`filterable` 标记为 `True`:
|
||||
|
||||
1. 字段名包含关键词:`name` / `title` / `code` / `mobile` / `phone` / `email` / `username` / `type` / `category` / `status` / `dept_id` / `role_id` 等
|
||||
2. 字段有数据库索引
|
||||
3. 整数字段且有选项
|
||||
|
||||
查询类型判断:
|
||||
- 字符串字段(非编码类)-> `模糊查询`(LIKE)
|
||||
- 编码字段(code/sn/no)-> `精确匹配`(=)
|
||||
- 整数字段 + 有选项 -> `精确匹配`(=)
|
||||
- 状态字段 -> `精确匹配`(=)
|
||||
|
||||
## 字段类型映射
|
||||
|
||||
### 数据库 -> Django 模型字段
|
||||
|
||||
| 数据库类型 | Django 字段类型 |
|
||||
|:----|:----|
|
||||
| varchar / char | CharField |
|
||||
| text / longtext | TextField |
|
||||
| int / tinyint / smallint | IntegerField |
|
||||
| bigint | IntegerField |
|
||||
| datetime / timestamp | DateTimeField |
|
||||
| date | DateField |
|
||||
| float / double | FloatField |
|
||||
| decimal | DecimalField |
|
||||
| boolean | BooleanField |
|
||||
|
||||
### Django 类型 -> 中文显示
|
||||
|
||||
| Django 类型 | 中文 |
|
||||
|:----|:----|
|
||||
| CharField | 字符串 |
|
||||
| TextField | 长文本 |
|
||||
| IntegerField | 整数 |
|
||||
| DateTimeField | 日期时间 |
|
||||
| DateField | 日期 |
|
||||
| FloatField | 浮点数 |
|
||||
| DecimalField | 小数 |
|
||||
| BooleanField | 布尔值 |
|
||||
|
||||
## 输出配置结构
|
||||
|
||||
`parse()` 返回的配置字典结构:
|
||||
|
||||
```python
|
||||
{
|
||||
"app_name": "example", # 模块名(去前缀小写)
|
||||
"module_comment": "案例", # 模块中文名(表注释去掉"表"字)
|
||||
"model_name": "example", # 模型名
|
||||
"model_class_name": "Example", # 模型类名(帕斯卡命名)
|
||||
"route_prefix": "example", # 路由前缀(下划线转斜杠)
|
||||
"permission_prefix": "sys:example", # 权限前缀
|
||||
"primary_key": "id", # 主键字段
|
||||
"display_field": "name", # 显示字段
|
||||
"display_field_camel": "name", # 显示字段驼峰
|
||||
"table_name": "example", # 表名(去前缀)
|
||||
"table_prefix": ["django_"], # 表前缀列表
|
||||
"remove_prefix": True, # 是否移除前缀
|
||||
"menu_group": "tool", # 菜单分组
|
||||
"parent_menu_id": 322, # 父级菜单ID
|
||||
"menu_sort": 5, # 菜单排序
|
||||
"has_sort": True, # 有排序字段
|
||||
"has_status": True, # 有状态字段
|
||||
"has_unique_code": False, # 有唯一编码字段
|
||||
"has_export": False, # 有导出功能
|
||||
"has_image_field": True, # 有图片字段
|
||||
"has_rich_text_field": False, # 有富文本字段
|
||||
"fields": [ # 字段配置列表
|
||||
{
|
||||
"name": "name",
|
||||
"comment": "案例名称",
|
||||
"purpose": "存储案例名称信息",
|
||||
"type": "CharField",
|
||||
"type_display": "字符串",
|
||||
"max_length": 100,
|
||||
"nullable": False,
|
||||
"required": True,
|
||||
"is_unique": False,
|
||||
"db_index": True,
|
||||
"default": None,
|
||||
"in_form": True,
|
||||
"in_list": True,
|
||||
"filterable": True,
|
||||
"filter_type": "模糊查询",
|
||||
"editable": True,
|
||||
"searchable": True,
|
||||
"is_image": False,
|
||||
"is_rich_text": False,
|
||||
},
|
||||
# ... 更多字段
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 与 CodeGenerator 的关系
|
||||
|
||||
```
|
||||
generator.py generator_config.py
|
||||
┌─────────────────────┐ ┌─────────────────────┐
|
||||
│ TableSchemaParser │ │ CodeGenerator │
|
||||
│ │ │ │
|
||||
│ information_schema │ config │ Jinja2 模板渲染 │
|
||||
│ ─────────────────> │ ────> │ ─────────────────> │
|
||||
│ 解析表结构 │ 字典 │ 生成文件 │
|
||||
└─────────────────────┘ └─────────────────────┘
|
||||
```
|
||||
|
||||
`generator.py` 负责"读",`generator_config.py` 负责"写",通过配置字典解耦。
|
||||
|
||||
## 总结
|
||||
|
||||
表结构解析引擎从数据库读取表和字段的元信息(类型、长度、注释、索引等),智能推断字段用途(图片、富文本、状态、排序、枚举、查询条件等),为代码生成器提供结构化的表描述数据。
|
||||
@@ -0,0 +1,295 @@
|
||||
:::tip 本章概要
|
||||
代码生成器模板的 Jinja2 语法说明,包括模板变量、字段属性和自定义模板的开发方法。
|
||||
:::
|
||||
|
||||
# 自定义模板
|
||||
|
||||
模板文件位于 `public/templates/`,使用 Jinja2 语法。修改模板后重新生成即可生效。
|
||||
|
||||
## 模板目录结构
|
||||
|
||||
```
|
||||
public/templates/
|
||||
├── models.py.tpl # ORM 模型
|
||||
├── forms.py.tpl # Django 表单验证
|
||||
├── services.py.tpl # 业务逻辑层
|
||||
├── views.py.tpl # 视图层
|
||||
├── urls.py.tpl # 路由配置
|
||||
├── apps.py.tpl # 应用配置
|
||||
├── admin.py.tpl # 后台管理
|
||||
├── ui/ # 普通分页列表模板
|
||||
│ ├── index.vue.tpl # 主页面
|
||||
│ ├── edit.vue.tpl # 编辑弹窗
|
||||
│ ├── detail.vue.tpl # 详情弹窗
|
||||
│ ├── columns.ts.tpl # 表格列定义
|
||||
│ ├── querySchemas.ts.tpl # 搜索表单 Schema
|
||||
│ └── api.ts.tpl # API 请求封装
|
||||
└── ui2/ # 树状列表模板
|
||||
├── index.vue.tpl # 树形主页面
|
||||
├── edit.vue.tpl # 树形编辑弹窗
|
||||
├── detail.vue.tpl # 树形详情弹窗
|
||||
└── columns.ts.tpl # 树形列定义
|
||||
```
|
||||
|
||||
## ui/ vs ui2/ 切换逻辑
|
||||
|
||||
当表中存在 `parent_id` 或 `pid` 字段时,自动切换为 `ui2/` 树形模板:
|
||||
|
||||
```
|
||||
字段列表中是否有 parent_id / pid?
|
||||
├── 是 -> 使用 ui2/ 模板(4 个组件 + 1 个 API)
|
||||
└── 否 -> 使用 ui/ 模板(5 个组件 + 1 个 API)
|
||||
```
|
||||
|
||||
两者共用 `ui/api.ts.tpl` 生成 API 接口文件。
|
||||
|
||||
## 模板变量
|
||||
|
||||
### 基础变量
|
||||
|
||||
| 变量 | 类型 | 说明 | 示例 |
|
||||
|:----|:----|:----|:----|
|
||||
| `app_name` | str | 模块名 | `example` |
|
||||
| `module_comment` | str | 中文名 | `案例` |
|
||||
| `module_name` | str | 模块名称(下划线移除) | `example` |
|
||||
| `model_class_name` | str | 类名 | `Example` |
|
||||
| `model_class_name_camel` | str | 驼峰类名(首字母小写) | `example` |
|
||||
| `route_prefix` | str | 路由前缀 | `example` |
|
||||
| `permission_prefix` | str | 权限前缀 | `sys:example` |
|
||||
| `display_field` | str | 显示字段 | `name` |
|
||||
| `display_field_camel` | str | 显示字段驼峰 | `name` |
|
||||
| `table_name` | str | 数据库表名 | `example` |
|
||||
| `primary_key` | str | 主键字段 | `id` |
|
||||
|
||||
### 功能标识
|
||||
|
||||
| 变量 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `has_sort` | bool | 有排序字段 |
|
||||
| `has_status` | bool | 有状态字段 |
|
||||
| `has_unique_code` | bool | 有唯一编码字段 |
|
||||
| `has_image_field` | bool | 有图片字段 |
|
||||
| `has_rich_text_field` | bool | 有富文本字段 |
|
||||
| `has_export` | bool | 有导出功能 |
|
||||
|
||||
### 字段列表
|
||||
|
||||
| 变量 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `fields` | list | 全部字段 |
|
||||
| `form_fields` | list | 表单字段(`in_form=True`) |
|
||||
| `list_fields` | list | 列表显示字段(`in_list=True`) |
|
||||
| `filter_fields` | list | 筛选字段(`filterable=True`) |
|
||||
| `filterable_fields` | list | 可过滤字段 |
|
||||
| `searchable_fields` | list | 可搜索字段 |
|
||||
| `editable_fields` | list | 可编辑字段 |
|
||||
|
||||
### 前端专用变量
|
||||
|
||||
| 变量 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `api_path` | str | API 路径(如 `tool/example`) |
|
||||
| `is_tree_structure` | bool | 是否树形结构 |
|
||||
| `parent_id_field` | str | 父级字段名 |
|
||||
| `has_search_form` | bool | 显示搜索表单 |
|
||||
| `show_selection` | bool | 显示复选框(树形结构) |
|
||||
| `action_column_width` | int | 操作列宽度(树形结构) |
|
||||
|
||||
## 字段对象属性
|
||||
|
||||
`fields` 列表中每个字段对象包含以下属性:
|
||||
|
||||
### 基础属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `name` | str | 字段名(snake_case) |
|
||||
| `camel_name` | str | 驼峰字段名 |
|
||||
| `comment` | str | 字段注释(原始) |
|
||||
| `label` | str | 清洗后的注释(去掉选项说明) |
|
||||
| `purpose` | str | 字段用途说明 |
|
||||
|
||||
### 类型属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `type` | str | Django 字段类型(CharField/IntegerField/...) |
|
||||
| `type_display` | str | 中文类型名 |
|
||||
| `model_field_type` | str | 模型字段类型 |
|
||||
| `form_field_type` | str | 表单字段类型 |
|
||||
| `max_length` | int | 最大长度 |
|
||||
|
||||
### 约束属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `nullable` | bool | 是否可空 |
|
||||
| `required` | bool | 是否必填 |
|
||||
| `is_unique` | bool | 是否唯一 |
|
||||
| `db_index` | bool | 是否有索引 |
|
||||
| `default` | any | 默认值 |
|
||||
|
||||
### 功能标识
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `is_image` | bool | 图片字段 |
|
||||
| `is_rich_text` | bool | 富文本字段 |
|
||||
|
||||
### 展示控制
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `in_form` | bool | 出现在表单中 |
|
||||
| `in_list` | bool | 出现在列表中 |
|
||||
| `editable` | bool | 可编辑 |
|
||||
| `filterable` | bool | 作为查询条件 |
|
||||
| `filter_type` | str | 筛选类型(`精确匹配`/`模糊查询`) |
|
||||
| `searchable` | bool | 可搜索 |
|
||||
|
||||
### 选项属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| `choices` | list | `[{value: any, label: str}, ...]` |
|
||||
| `choices_name` | str | 选项常量名 |
|
||||
| `min_value` | int | 最小值 |
|
||||
| `max_value` | int | 最大值 |
|
||||
|
||||
## 自定义模板示例
|
||||
|
||||
### 示例 1:为所有字段添加索引
|
||||
|
||||
修改 `public/templates/models.py.tpl`:
|
||||
|
||||
```jinja2
|
||||
{% if f.type == 'CharField' %}
|
||||
{{ f.name }} = models.CharField(
|
||||
max_length={{ f.max_length or 255 }},
|
||||
db_index=True,
|
||||
verbose_name="{{ f.comment }}",
|
||||
db_comment='{{ f.comment }}'
|
||||
)
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
### 示例 2:自定义 Service 验证逻辑
|
||||
|
||||
修改 `public/templates/services.py.tpl`,在添加方法中添加自定义校验:
|
||||
|
||||
```jinja2
|
||||
def add_{{ app_name }}(request):
|
||||
# ... 原有代码 ...
|
||||
# 自定义校验:检查名称是否重复
|
||||
if {{ model_class_name }}.objects.filter(name=cleaned_data.get('name'), is_delete=False).exists():
|
||||
return R.failed(msg="{{ module_comment }}名称已存在")
|
||||
# ... 创建记录 ...
|
||||
```
|
||||
|
||||
### 示例 3:自定义前端表格列宽
|
||||
|
||||
修改 `public/templates/ui/columns.ts.tpl`:
|
||||
|
||||
```jinja2
|
||||
{% for f in list_fields %}
|
||||
{
|
||||
label: '{{ f.label }}',
|
||||
prop: '{{ f.camel_name }}',
|
||||
minWidth: {{ 80 + (f.max_length or 100) // 3 }}, {# 动态列宽 #}
|
||||
},
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
## 新增模板
|
||||
|
||||
如需生成额外文件(如测试文件),按以下步骤操作:
|
||||
|
||||
### 第 1 步:创建模板文件
|
||||
|
||||
在 `public/templates/` 下新建 `test.py.tpl`:
|
||||
|
||||
```jinja2
|
||||
# tests/test_{{ app_name }}.py
|
||||
from django.test import TestCase
|
||||
from application.{{ app_name }}.models import {{ model_class_name }}
|
||||
|
||||
|
||||
class Test{{ model_class_name }}(TestCase):
|
||||
def test_create(self):
|
||||
"""测试创建{{ module_comment }}"""
|
||||
instance = {{ model_class_name }}.objects.create(
|
||||
name='测试',
|
||||
create_user='admin'
|
||||
)
|
||||
self.assertIsNotNone(instance.id)
|
||||
```
|
||||
|
||||
### 第 2 步:注册到 backend_templates
|
||||
|
||||
在 `generator_config.py` 的 `generate()` 方法中添加:
|
||||
|
||||
```python
|
||||
backend_templates = [
|
||||
'models.py.tpl',
|
||||
'forms.py.tpl',
|
||||
'services.py.tpl',
|
||||
'views.py.tpl',
|
||||
'urls.py.tpl',
|
||||
'apps.py.tpl',
|
||||
'admin.py.tpl',
|
||||
'test.py.tpl', # 新增
|
||||
]
|
||||
```
|
||||
|
||||
### 第 3 步:调整输出路径(可选)
|
||||
|
||||
如果需要输出到非默认目录,修改 `generate()` 方法中的路径逻辑。
|
||||
|
||||
## Jinja2 语法速查
|
||||
|
||||
```jinja2
|
||||
{# 注释 #}
|
||||
|
||||
{# 变量输出 #}
|
||||
{{ app_name }}
|
||||
{{ f.name | upper }}
|
||||
|
||||
{# 条件判断 #}
|
||||
{% if has_status %}
|
||||
# 有状态字段
|
||||
{% elif has_sort %}
|
||||
# 有排序字段
|
||||
{% else %}
|
||||
# 都没有
|
||||
{% endif %}
|
||||
|
||||
{# 循环 #}
|
||||
{% for f in fields %}
|
||||
{{ f.name }}
|
||||
{% endfor %}
|
||||
|
||||
{# 循环 + 条件过滤 #}
|
||||
{% for f in fields if f.is_image %}
|
||||
{{ f.name }}
|
||||
{% endfor %}
|
||||
|
||||
{# 循环变量 #}
|
||||
{% for f in fields %}
|
||||
{{ loop.index }} {# 从 1 开始 #}
|
||||
{{ loop.first }} {# 是否第一个 #}
|
||||
{{ loop.last }} {# 是否最后一个 #}
|
||||
{% endfor %}
|
||||
|
||||
{# 三元表达式 #}
|
||||
{{ 'True' if f.nullable else 'False' }}
|
||||
|
||||
{# 字符串拼接 #}
|
||||
{{ app_name }}_service
|
||||
|
||||
{# 默认值 #}
|
||||
{{ f.max_length or 255 }}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
模板使用 Jinja2 语法,每个模板对应一个生成文件。模板变量包括模块名、表名、字段列表等,字段属性包含名称、类型、注释、是否可搜索等。可通过修改模板自定义生成代码的风格和结构。
|
||||
@@ -0,0 +1,136 @@
|
||||
:::tip 本章概要
|
||||
代码生成器 Web 管理界面的使用方法,通过可视化界面操作单表生成和批量生成。
|
||||
:::
|
||||
|
||||
# Web 管理界面
|
||||
|
||||
登录管理后台,进入「开发工具 -> 代码生成」页面,可通过可视化界面操作代码生成。
|
||||
|
||||
:::warning 数据库要求
|
||||
代码生成器的 Web 界面通过查询 MySQL 的 `information_schema` 获取表结构信息,**仅支持 MySQL 数据库**。
|
||||
:::
|
||||
|
||||
## 操作流程
|
||||
|
||||
完整操作流程:
|
||||
|
||||
```
|
||||
1. 登录管理后台
|
||||
2. 左侧菜单 -> 开发工具 -> 代码生成
|
||||
3. 在表列表中搜索目标表(支持表名/表注释模糊搜索)
|
||||
4. 点击表名可查看字段详情(字段名、类型、注释、是否可空等)
|
||||
5. 单表生成:点击行末「生成」按钮
|
||||
批量生成:勾选多表 -> 点击「批量生成」按钮
|
||||
6. 生成成功后,左侧菜单自动出现新模块入口
|
||||
7. 进入新模块页面,测试增删改查功能
|
||||
```
|
||||
|
||||
## 单表生成
|
||||
|
||||
1. 在表列表中搜索目标表(支持表名和表注释模糊搜索)
|
||||
2. 点击目标表行的「生成」按钮
|
||||
3. 系统自动解析表结构并生成全部代码
|
||||
4. 生成完成后提示成功
|
||||
|
||||
## 批量生成
|
||||
|
||||
1. 勾选多个表(左侧复选框)
|
||||
2. 点击表格上方的「批量生成」按钮
|
||||
3. 系统逐表生成,完成后提示成功数量
|
||||
|
||||
## API 接口
|
||||
|
||||
Web 界面底层调用 `application/generator/` 模块的 API 接口:
|
||||
|
||||
### 查询表分页
|
||||
|
||||
```
|
||||
GET /generator/page?pageNo=1&pageSize=10&tableName=example
|
||||
```
|
||||
|
||||
返回数据库表的分页数据,支持按表名和表注释模糊搜索。
|
||||
|
||||
### 查询表详情
|
||||
|
||||
```
|
||||
GET /generator/detail?tableName=django_example
|
||||
```
|
||||
|
||||
返回单个表的元数据(表名、注释、引擎、行数、字符集等)。
|
||||
|
||||
### 查询表字段
|
||||
|
||||
```
|
||||
GET /generator/columns?tableName=django_example
|
||||
```
|
||||
|
||||
返回表的字段列表(字段名、类型、注释、是否可空、默认值等)。
|
||||
|
||||
### 代码生成
|
||||
|
||||
```
|
||||
POST /generator/generate
|
||||
```
|
||||
|
||||
请求体:
|
||||
|
||||
```json
|
||||
{
|
||||
"tableNames": [
|
||||
"django_example|案例表",
|
||||
"django_product|商品表"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`tableNames` 支持三种格式:
|
||||
|
||||
| 格式 | 示例 | 说明 |
|
||||
|:----|:----|:----|
|
||||
| 管道分隔 | `"django_example\|案例表"` | 表名\|注释,注释覆盖数据库表注释 |
|
||||
| 纯表名 | `"django_example"` | 注释从数据库读取 |
|
||||
| 字典 | `{"name": "django_example", "comment": "案例表"}` | 结构化格式 |
|
||||
|
||||
成功返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "本次共计生成2个模块",
|
||||
"data": null,
|
||||
"ok": true
|
||||
}
|
||||
```
|
||||
|
||||
## 权限节点
|
||||
|
||||
| 权限标识 | 说明 |
|
||||
|:----|:----|
|
||||
| `sys:generator:page` | 查询表分页 |
|
||||
| `sys:generator:detail` | 查询表详情/字段 |
|
||||
| `sys:generator:generate` | 代码生成 |
|
||||
|
||||
## 与 CLI 的对比
|
||||
|
||||
| 维度 | CLI | Web 界面 |
|
||||
|:----|:----|:----|
|
||||
| 入口 | `python generator.py <表名>` | 开发工具 -> 代码生成 |
|
||||
| 适用场景 | 开发阶段,快速生成 | 运维阶段,可视化操作 |
|
||||
| 批量生成 | 不支持(循环调用) | 支持(勾选多表) |
|
||||
| 配置微调 | `--output` 导出 -> 编辑 -> `--config` 导入 | 不支持(直接生成) |
|
||||
| 生成结果 | 完全一致 | 完全一致 |
|
||||
| 预览模式 | `--dry-run` | 不支持 |
|
||||
|
||||
## 实现原理
|
||||
|
||||
Web 界面的后端实现在 `application/generator/` 模块中:
|
||||
|
||||
- `services.py`:核心业务逻辑,包含 `get_table_page()`、`get_table_detail()`、`get_table_columns()`、`generate_tables()` 等函数
|
||||
- `views.py`:视图层,处理 HTTP 请求并调用 services
|
||||
- `urls.py`:路由配置
|
||||
|
||||
`generate_tables()` 函数内部调用 `generator.py` 的 `generate_config_from_table()` 解析表结构,再调用 `generator_config.py` 的 `CodeGenerator` 生成代码(自动模式 `auto=True`,跳过交互确认)。
|
||||
|
||||
## 总结
|
||||
|
||||
Web 管理界面提供可视化的代码生成操作,支持单表生成和批量生成。通过选择数据库表、配置生成选项,一键生成前后端全套代码并自动注册路由和权限。底层与 CLI 共享同一套引擎代码。
|
||||
Reference in New Issue
Block a user