Files
djangoadmin-wiki/DjangoAdmin_Flask_NaiveVue/zh/volume4/business/example.md
T
2026-09-12 23:12:15 +08:00

7.0 KiB
Raw Blame History

:::tip 案例演示 案例演示模块是代码生成器的参考模板,展示了标准 CRUD 模块的完整实现。包含文件字段处理、枚举字典映射、状态管理等功能,可作为新模块开发的参考范例。 :::

模块结构

src/modules/example/
├── models.py     # 案例模型
├── schema.py     # 表单验证(WTForms)
├── repository.py # 数据访问层
├── service.py    # 业务逻辑层(继承 BaseService)
└── router.py     # 路由控制器

案例模型

# src/modules/example/models.py
class Example(BaseModel, BaseDB):
    """
    案例演示模型

    包含文件字段(avatar)、枚举字段(type/status)等典型业务字段。
    """
    __tablename__ = DB_PREFIX + "example"
    __table_comment__ = "案例演示表"

    # 案例名称
    name = db.Column(db.String(255), nullable=False, index=True, comment="案例名称")
    # 案例图片(存相对路径)
    avatar = db.Column(db.String(255), nullable=False, comment="案例图片")
    # 案例类型:1-类型1 2-类型2 3-类型3 4-类型4
    type = db.Column(db.Integer, nullable=True, default=0, server_default=text('0'),
                     comment="案例类型:1-类型1 2-类型2 3-类型3 4-类型4")
    # 案例状态:1-在用 2-停用
    status = db.Column(db.Integer, nullable=True, default=0, server_default=text('0'),
                       index=True, comment="案例状态:1-在用 2-停用")
    # 排序
    sort = db.Column(db.Integer, nullable=True, default=0, server_default=text('0'),
                     comment="案例排序")

服务层实现

# src/modules/example/service.py
class ExampleService(BaseService):
    """
    案例演示服务类

    展示文件字段处理、枚举映射等标准 CRUD 模式。
    """
    repository = ExampleRepository
    form = ExampleForm
    status_form = ExampleStatusForm
    model_name = "案例演示"

    @classmethod
    def before_add(cls, form):
        """新增前钩子:处理文件字段"""
        _handle_file_fields(form)

    @classmethod
    def before_update(cls, form, obj):
        """更新前钩子:处理文件字段"""
        _handle_file_fields(form)

    @classmethod
    def _enrich_page_records(cls, records):
        """分页富化:文件字段拼接 URL"""
        for data in records:
            data["avatar"] = get_file_url(data.get("avatar"))
        return records

    @classmethod
    def _detail_dict(cls, obj):
        """详情序列化:文件字段拼接 URL"""
        data = model_to_dict(obj)
        data["avatar"] = get_file_url(data.get("avatar"))
        return data


def _handle_file_fields(form):
    """文件字段处理:临时文件迁移到正式目录"""
    avatar = form.data.get("avatar")
    if avatar:
        form.avatar.data = save_file(avatar, "example")

文件字段处理模式

这是项目中处理文件字段的标准模式:

步骤 时机 处理
1. 前端上传 用户选择文件 上传到临时目录,获得临时 URL
2. 提交表单 前端提交 将临时 URL 传给后端
3. before_add/before_update Service 钩子 save_file 迁移到正式目录
4. 存储数据库 Repository.create 存相对路径
5. 查询返回 _detail_dict/_enrich_page_records get_file_url 拼接完整 URL

枚举字段映射

通过 serialize_maps 声明枚举字段与字典编码的映射:

class ExampleService(BaseService):
    serialize_maps = {
        'type': 'example_type',      # 案例类型 → 数据字典
        'status': 'example_status'   # 案例状态 → 数据字典
    }

查询结果自动包含 typeText 和 statusText 字段。

表单验证

# src/modules/example/schema.py
class ExampleForm(BaseForm):
    """案例创建/编辑表单"""
    name = StringField('案例名称', validators=[
        DataRequired(message='案例名称不能为空'),
        Length(max=255, message='案例名称长度不得超过255个字符')
    ])
    avatar = StringField('案例图片', validators=[Optional(), Length(max=255)])
    type = IntegerField('案例类型', validators=[
        Optional(), NumberRange(min=1, max=4, message='案例类型值在1~4之间')
    ])
    status = IntegerField('案例状态', validators=[
        Optional(), NumberRange(min=1, max=2, message='案例状态值在1~2之间')
    ])
    sort = IntegerField('案例排序', validators=[
        Optional(), NumberRange(min=0, max=99999)
    ])

    def validate_name(self, field):
        """案例名称唯一性校验"""
        if not field.data:
            return
        current_id = self.id.data if self.id.data else None
        if ExampleRepository.exists_by({'name': field.data}, exclude_id=current_id):
            raise ValidationError("案例名称已存在")


class ExampleStatusForm(BaseForm):
    """案例状态更新表单"""
    id = IntegerField('案例ID', validators=[
        DataRequired(message='案例ID不能为空'),
        NumberRange(min=1, message='案例ID必须大于0')
    ])
    status = IntegerField('案例状态', validators=[
        DataRequired(message='案例状态不能为空'),
        NumberRange(min=1, max=2, message='案例状态值在1~2之间')
    ])

API 接口

方法 路径 权限节点 说明
GET /api/v1/example/page sys:example:page 分页查询
GET /api/v1/example/detail/<id> sys:example:detail 详情查询
GET /api/v1/example/list sys:example:list 列表查询(无分页)
POST /api/v1/example/add sys:example:add 新增案例
PUT /api/v1/example/update sys:example:update 编辑案例
DELETE /api/v1/example/delete/<id> sys:example:delete 删除案例
DELETE /api/v1/example/batchDelete sys:example:batchDelete 批量删除
PUT /api/v1/example/status sys:example:status 设置状态

数据字典

字典编码 用途 字典项示例
example_type 案例类型名称 1=类型1, 2=类型2, 3=类型3, 4=类型4
example_status 案例状态名称 1=在用, 2=停用

作为代码生成器参考

案例演示模块是代码生成器的参考模板,新模块开发时可参考其模式:

  1. 模型定义:继承 BaseModel + BaseDB,字段注释完整
  2. 表单验证:继承 BaseForm,validate_ 方法实现唯一性校验
  3. 数据访问:继承 BaseRepository,实现 page() / list_enabled()
  4. 业务服务:继承 BaseService,声明 repository / form / model_name
  5. 路由控制:Blueprint + @check_permission + @check_demo + @operation_log

总结

案例演示模块是标准 CRUD 模块的参考范例,展示了文件字段处理(save_file/get_file_url)、枚举字典映射(serialize_maps)、状态管理(update_status)等典型模式。新模块开发或代码生成器生成的代码均以此模块为参考。