Files
djangoadmin-wiki/DjangoAdmin_Tornado_NaiveVue/zh/volume7/handler.md
T
2026-09-16 13:28:20 +08:00

4.6 KiB
Raw Blame History

Handler 层规范

概述

Handler 层是 HTTP 接口层,定义路由和请求处理。每个模块的 Handler 文件位于 src/modules/{name}/handlers.py,使用 Tornado Handler 类定义接口。

:::tip 设计原则

  • Handler 只做请求分发,不含业务逻辑
  • 通过装饰器控制权限和演示模式
  • 委托 Service 处理业务逻辑
  • 返回 R 封装的响应 :::

装饰器顺序

class PositionAddHandler(BaseHandler):
    @permission_required("sys:position:add")    # 1. 权限校验
    @check_demo                                  # 2. 演示模式拦截
    @operation_log("岗位管理", "添加")           # 3. 操作日志
    async def post(self):
        return await position_service.add(self)

:::warning 装饰器顺序规则

  1. @permission_required("权限标识"):RBAC 权限校验
  2. @check_demo:演示环境写操作拦截(仅写接口需要)
  3. @operation_log("模块", "动作"):操作日志记录(仅写接口需要)

顺序不可调换,否则权限校验或演示拦截可能失效。 :::

读操作(无需 @check_demo)

class PositionPageHandler(BaseHandler):
    @permission_required("sys:position:list")
    async def get(self):
        return await position_service.get_page(self)

class PositionDetailHandler(BaseHandler):
    @permission_required("sys:position:detail")
    async def get(self, id):
        return R.ok(self, data=position_service.get_detail(id))

class PositionGetListHandler(BaseHandler):
    @permission_required("sys:position:list")
    async def get(self):
        return R.ok(self, data=position_service.get_options(self))

写操作(需要 @check_demo + @operation_log)

class PositionAddHandler(BaseHandler):
    @permission_required("sys:position:add")
    @check_demo
    @operation_log("岗位管理", "添加")
    async def post(self):
        return await position_service.add(self)

class PositionUpdateHandler(BaseHandler):
    @permission_required("sys:position:update")
    @check_demo
    @operation_log("岗位管理", "更新")
    async def put(self):
        return await position_service.update(self)

class PositionDeleteHandler(BaseHandler):
    @permission_required("sys:position:delete")
    @check_demo
    @operation_log("岗位管理", "删除")
    async def delete(self, id):
        return await position_service.delete(self, id)

class PositionStatusHandler(BaseHandler):
    @permission_required("sys:position:status")
    @check_demo
    @operation_log("岗位管理", "设置状态")
    async def put(self):
        return await position_service.update_status(self)

class PositionBatchDeleteHandler(BaseHandler):
    @permission_required("sys:position:delete")
    @check_demo
    @operation_log("岗位管理", "批量删除")
    async def post(self):
        return await position_service.batch_delete(self)

权限标识规范

权限标识格式:sys:{module}:{action}

操作 权限标识 HTTP 方法
分页查询 sys:{module}:list GET
详情查询 sys:{module}:detail GET
下拉列表 sys:{module}:list GET
添加 sys:{module}:add POST
编辑 sys:{module}:update PUT
删除 sys:{module}:delete DELETE
批量删除 sys:{module}:delete POST
状态设置 sys:{module}:status PUT

:::tip admin 用户 用户 ID 为 1 的管理员账号跳过所有 permission_required 检查。 :::

路由注册

在 src/api/v1/{module}.py 中定义路由列表,在 src/api/v1/router.py 中注册:

# src/api/v1/position.py
from modules.position.handlers import (
    PositionPageHandler, PositionDetailHandler, PositionAddHandler,
    PositionUpdateHandler, PositionDeleteHandler, PositionStatusHandler,
    PositionBatchDeleteHandler,
)

routes = [
    (r"/position/page", PositionPageHandler),
    (r"/position/detail/(\d+)", PositionDetailHandler),
    (r"/position/add", PositionAddHandler),
    (r"/position/update", PositionUpdateHandler),
    (r"/position/delete/(\d+)", PositionDeleteHandler),
    (r"/position/status", PositionStatusHandler),
    (r"/position/batchDelete", PositionBatchDeleteHandler),
]
# src/api/v1/router.py
from api.v1 import position
_RESOURCE_MODULES = [..., position]

总结

Handler 层是 HTTP 接口定义层,只做请求分发和装饰器配置。核心规则:装饰器顺序为 @permission_required → @check_demo → @operation_log;读操作无需 @check_demo 和 @operation_log;权限标识格式 sys:{module}:{action};所有逻辑委托 Service 处理。