flask 路由 add_url_rule 、@app.route app.test_request_context()

张开发
2026/4/17 18:41:56 15 分钟阅读

分享文章

flask 路由 add_url_rule 、@app.route app.test_request_context()
fromflaskimportFlask appFlask(__name__)defhello():returnHello, World!# 注册路由app.add_url_rule(/,hello,hello)# 等价于# app.route(/)# def hello():# return Hello, World!# 带变量的路由defuser_profile(username):returnf用户:{username}app.add_url_rule(/user/username,user_profile,user_profile)# 带类型转换器defpost_detail(post_id):returnf文章ID:{post_id}app.add_url_rule(/post/int:post_id,post_detail,post_detail)# 指定 请求方式的defuser_list():ifrequest.methodGET:return获取用户列表elifrequest.methodPOST:return创建新用户app.add_url_rule(/users,user_list,user_list,methods[GET,POST])# 等价于# app.route(/users, methods[GET, POST])# def user_list():# ...app.test_request_context()返回一个请求上下文对象RequestContext它模拟一个 HTTP 请求环境让你可以在没有实际请求的情况下使用 Flask 的请求相关功能。fromflaskimportFlask,url_for,request,session appFlask(__name__)# 调用 test_request_context() 返回一个上下文对象ctxapp.test_request_context()print(type(ctx))# class flask.ctx.RequestContext# 在没有请求时使用 url_for()# ❌ 这样会报错没有应用上下文# url_for(index) # RuntimeError: Working outside of application context# ✅ 使用 test_request_contextwithapp.test_request_context():urlurl_for(index)# 正常工作print(url)# /# 模拟请求数据路径、参数、方法等# 模拟 GET 请求带查询参数withapp.test_request_context(/search?qflaskpage2):print(request.method)# GETprint(request.path)# /searchprint(request.args)# ImmutableMultiDict([(q, flask), (page, 2)])print(request.args.get(q))# flask# 模拟 POST 请求带表单数据withapp.test_request_context(/login,methodPOST,data{username:admin,password:123}):print(request.method)# POSTprint(request.form)# ImmutableMultiDict([(username, admin), (password, 123)])print(request.form[username])# admin# 模拟 JSON 数据withapp.test_request_context(/api,json{name:张三,age:20}):print(request.json)# {name: 张三, age: 20}# 模拟携带请求头withapp.test_request_context(/,headers{User-Agent:Mozilla/5.0,X-Custom-Header:test}):print(request.headers.get(User-Agent))# Mozilla/5.0print(request.headers.get(X-Custom-Header))# test# 操作sessionwithapp.test_request_context():session[user_id]123session[username]adminprint(session.get(user_id))# 123# 手动调用视图函数app.route(/user/int:user_id)defuser_profile(user_id):returnfUser{user_id}# 测试视图函数withapp.test_request_context(/user/42):# 手动调用视图函数responseuser_profile(42)print(response)# User 42# 测试需要请求数据的视图函数app.route(/login,methods[POST])deflogin():usernamerequest.form.get(username)passwordrequest.form.get(password)ifusernameadminandpasswordsecret:session[user]usernamereturn登录成功return登录失败,401# 测试登录功能withapp.test_request_context(/login,methodPOST,data{username:admin,password:secret}):responselogin()print(response)# 登录成功print(session.get(user))# admin批量注册路由》》使用列表批量注册路由defindex():return首页defabout():return关于defcontact():return联系我们routes[(/,index,index),(/about,about,about),(/contact,contact,contact),]forrule,endpoint,view_funcinroutes:app.add_url_rule(rule,endpoint,view_func)》》》使用字典批量注册路由routes_config{/:{endpoint:home,view_func:index,methods:[GET]},/admin:{endpoint:admin,view_func:admin,methods:[GET,POST]},}forrule,configinroutes_config.items():app.add_url_rule(rule,**config)# 在蓝图中使用fromflaskimportBlueprint adminBlueprint(admin,__name__)defdashboard():return管理后台# 在蓝图上使用 add_url_ruleadmin.add_url_rule(/dashboard,dashboard,dashboard)# 注册蓝图app.register_blueprint(admin,url_prefix/admin)# 根据条件注册路由defregister_debug_routes(app):仅在调试模式下注册的路由ifapp.debug:defdebug_info():return调试信息app.add_url_rule(/debug,debug_info,debug_info)register_debug_routes(app)# 动态添加路由运行时defdynamic_page(name):returnf动态页面:{name}# 运行时动态添加路由page_nametestapp.add_url_rule(f/{page_name},page_name,dynamic_page)# 甚至可以循环添加pages[about,service,product]forpageinpages:defview_func(pagepage):# 注意捕获变量returnf这是{page}页面app.add_url_rule(f/{page},page,view_func)类视图的注册fromflask.viewsimportViewclassUserView(View):defdispatch_request(self):return用户页面# 注册类视图app.add_url_rule(/users,view_funcUserView.as_view(user_list))# MethodView 示例fromflask.viewsimportMethodViewclassUserAPI(MethodView):defget(self):return获取用户defpost(self):return创建用户app.add_url_rule(/api/users,view_funcUserAPI.as_view(user_api))# 它内部大致做了这些工作defas_view(name):# 1. 创建一个闭包函数defview(**kwargs):# 2. 实例化 UserView 类instanceUserView()# 3. 调用 dispatch_request 方法returninstance.dispatch_request(**kwargs)# 4. 给这个函数起个名字用于 endpointview.__name__namereturnview# 返回一个真正的函数# ✅ 正确通过 as_view 转换app.add_url_rule(/users,view_funcUserView.as_view(user_list))# 相当于手动写了一个函数视图defuser_list():returnUserView().dispatch_request()app.add_url_rule(/users,view_funcuser_list)

更多文章