322 lines
10 KiB
Markdown
322 lines
10 KiB
Markdown
:::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 + 前端页面 + 路由注册 + 菜单权限。生成后根据业务需求进行微调即可投入使用。
|