如何在FastHTML中拆分路由至独立模块?
如何在FastHTML中拆分路由至独立模块?
当然可以!FastHTML 底层基于 FastAPI,所以拆分路由的思路和 FastAPI 完全兼容,咱们有两种非常实用的方案,你可以根据项目规模来选:
方案一:直接导入主app实例注册路由(简单直接,适合小型项目)
这种方式不需要额外工具,只要把路由函数放在单独文件里,导入主文件中已经创建好的 app 实例就行,步骤如下:
1. 改造主文件(比如命名为 main.py)
把原来的路由代码移出去,只保留 app 初始化、静态文件挂载和服务启动的逻辑:
from fasthtml import common as fh from fastapi.staticfiles import StaticFiles import xmother # 你的自定义模块 # 导入拆分后的路由文件,注意要在app创建完成后导入 from routes import tree_routes, field_routes myHeaders = [ fh.Meta(charset='UTF-8'), fh.Meta(name='viewport', content='width=device-width, initial-scale=1'), fh.Link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css') ] # 创建 FastHTML App app = fh.FastHTML(hdrs=myHeaders, secret_key=xmother.newId(25)) # 挂载静态文件夹 app.mount("/static", StaticFiles(directory="static"), name="static") # 启动服务 fh.serve()
2. 拆分路由到单独文件
在项目根目录创建 routes 文件夹,然后分别创建路由文件:
routes/tree_routes.py(树形菜单路由)
from main import app # 导入主文件的app实例 from fasthtml import Request # 导入你的自定义函数和模块 import xmother from your_modules import getGeneralTreeViewCodeFH, menuDict ''' 执行主视图:树形菜单 ''' @app.get("/softprop/tree") def geto2(request: Request): request.session['id'] = xmother.newId(10) # 设置会话ID return getGeneralTreeViewCodeFH(menuDict=menuDict)
routes/field_routes.py(字段事件响应路由)
from main import app from fasthtml import Request from your_modules import menu_params ''' 响应字段事件 ''' @app.get("/softprop/fieldEvent") def getFieldEvent(request: Request): return menu_params.getFieldEventDef(request)
这样一来,当主文件导入这些路由模块时,装饰器会自动把路由注册到 app 实例上,非常省心~
方案二:使用APIRouter(解耦性强,适合中大型项目)
如果你的项目路由很多,用 APIRouter 会更清晰,它可以让路由模块不直接依赖主 app 实例,实现完全解耦:
1. 创建带APIRouter的路由文件
还是在 routes 文件夹下,每个路由模块创建自己的 APIRouter 实例:
routes/tree_routes.py
from fasthtml import APIRouter, Request import xmother from your_modules import getGeneralTreeViewCodeFH, menuDict # 可以设置统一前缀,比如这里的"/softprop",后续路由就不用重复写了 router = APIRouter(prefix="/softprop") @router.get("/tree") def geto2(request: Request): request.session['id'] = xmother.newId(10) return getGeneralTreeViewCodeFH(menuDict=menuDict)
routes/field_routes.py
from fasthtml import APIRouter, Request from your_modules import menu_params router = APIRouter(prefix="/softprop") @router.get("/fieldEvent") def getFieldEvent(request: Request): return menu_params.getFieldEventDef(request)
2. 主文件中包含路由
回到 main.py,把各个路由模块的 router 包含到主 app 中:
from fasthtml import common as fh from fastapi.staticfiles import StaticFiles from routes.tree_routes import router as tree_router from routes.field_routes import router as field_router import xmother myHeaders = [ fh.Meta(charset='UTF-8'), fh.Meta(name='viewport', content='width=device-width, initial-scale=1'), fh.Link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css') ] app = fh.FastHTML(hdrs=myHeaders, secret_key=xmother.newId(25)) app.mount("/static", StaticFiles(directory="static"), name="static") # 把路由包含到主app app.include_router(tree_router) app.include_router(field_router) # 更多路由继续用include_router添加即可 fh.serve()
注意事项
- 方案一中,一定要确保在创建完
app实例之后再导入路由文件,否则会出现app未定义的错误; - 如果用相对路径导入模块出现问题,可以把项目根目录添加到Python路径,或者调整导入语句;
- 不管用哪种方案,你的自定义函数(比如
getGeneralTreeViewCodeFH、menu_params)都要保证导入路径正确哦~
备注:内容来源于stack exchange,提问作者Ximo Dante
相关产品推荐
相关产品推荐

