PythonFlask框架详解

PythonFlask框架详解

2023年7月4日发(作者:)

PythonFlask框架详解记录请求使⽤的HTTP⽅法  Flask 本⾝相当于⼀个内核,其他⼏乎所有的功能都要⽤到扩展,都需要⽤第三⽅的扩展来实现,⽐如可以⽤ Flask 扩展加⼊ORM、窗体验证⼯具,⽂件上传、⾝份验证等。Flask 没有默认使⽤的数据库,你可以选择 MySQL,也可以⽤ NoSQL。  其 WSGI ⼯具箱采⽤ Werkzeug(路由模块),模板引擎则使⽤ Jinja2。这两个也是 Flask 框架的核⼼。Flask常⽤扩展包:Flask-SQLalchemy:操作数据库;Flask-script:插⼊脚本;Flask-migrate:管理迁移数据库;Flask-Session:Session存储⽅式指定;Flask-WTF:表单;Flask-Mail:邮件;Flask-Bable:提供国际化和本地化⽀持,翻译;Flask-Login:认证⽤户状态;Flask-OpenID:认证;Flask-RESTful:开发REST API的⼯具;Flask-Bootstrap:集成前端Twitter Bootstrap框架;Flask-Moment:本地化⽇期和时间;Flask-Admin:简单⽽可扩展的管理接⼝的框架1. 中⽂⽂档()2. 英⽂⽂档()3. 扩展列表:#安装pip install flask==0.10.1 # 后⾯为版本号1、新建⽂件# 导⼊Flask类from flask import Flask# Flask函数接收⼀个参数__name__,它会指向程序所在的包app = Flask(__name__)# 装饰器的作⽤是将路由映射到视图函数 index@('/')def index(): return 'Hello World'# Flask应⽤程序实例的 run ⽅法 启动 WEB 服务器if __name__ == '__main__': () # 可以指定运⾏的主机IP地址,端⼝,是否开启调试模式 # (host="0.0.0.0", port=8888, debug = True)2、相关配置参数Flask 程序实例在创建的时候,需要默认传⼊当前 Flask 程序所指定的包(模块)app = Flask(__name__)import_nameFlask程序所在的包(模块),传

__name__ 就可以其可以决定 Flask 在访问静态⽂件时查找的路径static_path静态⽂件访问路径(不推荐使⽤,使⽤ static_url_path 代替)static_url_path静态⽂件访问路径,可以不传,默认为:/ + static_folderstatic_folder静态⽂件存储的⽂件夹,可以不传,默认为

statictemplate_folder模板⽂件存储的⽂件夹,可以不传,默认为

templates3.加载配置⽂件在 Flask 程序运⾏的时候,可以给 Flask 设置相关配置,⽐如:配置 Debug 模式,配置数据库连接地址等等,设置 Flask 配置有以下三种⽅式:从配置对象中加载(常⽤)_object()从配置⽂件中加载_pyfile()从环境变量中加载(不常⽤)_envvar()3.1配置对象加载# 配置对象,⾥⾯定义需要给 APP 添加的⼀系列配置class Config(object): DEBUG = True# 创建 Flask 类的对象,指向程序所在的包的名称app = Flask(__name__)# 从配置对象中加载配置_object(Config)3.2配置⽂件加载创建配置⽂件

,在配置⽂件中添加配置格式eg: DEBUG = True# 创建 Flask 类的对象,指向程序所在的包的名称app = Flask(__name__)# 从配置⽂件中加载配置_pyfile('')3.4读取配置()在视图函数中使⽤ current_()注:Flask 应⽤程序将⼀些常⽤的配置设置成了应⽤程序对象的属性,也可以通过属性直接设置/获取某些配置: = True4 路由定义4.1指定路由地址# 指定访问路径为 hello@('/hello')def demo1(): return 'hello world'4.2 给路由传参# 路由传递参数@('/user/')def user_info(user_id): return 'hello %s' % user_id# 路由传递的参数默认当做 string 处理,也可以指定参数的类型# 路由传递参数@('/user/')def user_info(user_id): return 'hello %d' % user_id4.3指定请求⽅式在 Flask 中,定义⼀个路由,默认的请求⽅式为:GETOPTIONS(⾃带)HEAD(⾃带)@('/login', methods=['GET', 'POST']) # ⽀持GET和POST,并且⽀持⾃带的OPTIONS和HEADdef login(): # 直接从请求中取到请求⽅式并返回 return 4.4 正则匹配路由在 web 开发中,可能会出现限制⽤户访问规则的场景,那么这个时候就需要⽤到正则匹配,根据⾃⼰的规则去限定请求参数再进⾏访问具体实现步骤为:导⼊转换器基类:在 Flask 中,所有的路由的匹配规则都是使⽤转换器对象进⾏记录⾃定义转换器:⾃定义类继承于转换器基类添加转换器到默认的转换器字典中使⽤⾃定义转换器实现⾃定义匹配规则(1)导⼊转换器基类from g import BaseConverter(2)⾃定义转换器from flask import Flask, redirect, url_forfrom g import BaseConverterclass RegexConverter(BaseConverter): def __init__(self, url_name, *args): super().__init__(url_name) # 将接受的第1个参数当作匹配规则进⾏保存 = args[0]class ListConverter(BaseConverter): regex = '(d+,?)+d$' def to_python(self, value): return (",") def to_url(self, value): return ",".join(str(i) for i in value)(3)添加转换器到默认的转换器字典中,并指定转换器使⽤时名字为: reapp = Flask(__name__)# 将⾃定义转换器添加到转换器字典中,并指定转换器使⽤时名字为: _ters["re"] = RegexConverter# 将⾃定义转换器添加到转换器字典中,并指定转换器使⽤时名字为: _ters["list"] = ListConverter(4)使⽤转换器去实现⾃定义匹配规则@("/demo/")def demo1(use_name): return "⽤户名是 %s" % use_name@("/users/")def demo11(user_list): return "⽤户列表为 %s" % user_list# 系统⾃带转换器DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter,}# 系统⾃带的转换器具体使⽤⽅式在每种转换器的注释代码中有写,请留意每种转换器初始化的参数⾃定义转换器其他两个函数实现:继承于⾃定义转换器之后,还可以实现 to_python 和 to_url 这两个函数去对匹配参数做进⼀步处理:to_python:该函数参数中的 value 值代表匹配到的值,可输出进⾏查看匹配完成之后,对匹配到的参数作最后⼀步处理再返回,⽐如:转成 int 类型的值再返回:class RegexConverter(BaseConverter): def __init__(self, url_map, *args): super(RegexConverter, self).__init__(url_map) # 将接受的第1个参数当作匹配规则进⾏保存 = args[0] def to_python(self, value): return int(value) # 在视图函数中可以查看参数的类型,由之前默认的 str 已变成 int 类型的值  to_url:  在使⽤ url_for 去获取视图函数所对应的 url 的时候,会调⽤此⽅法对 url_for 后⾯传⼊的视图函数参数做进⼀步处理  具体可参见 Flask 的 中写的⽰例代码:ListConverter 5.简单视图5.1 返回json在使⽤ Flask 给客户端返回 JSON 数据时,可以直接使⽤ jsonify ⽣成⼀个 JSON 的响应# 返回JSON@('/demo')def demo(): json_dict = { "user_id": 10, "user_name": "laowang" } return jsonify(json_dict)注:不推荐使⽤ 转成 JSON 字符串直接返回,因为返回的数据要符合 HTTP 协议规范,如果是 JSON 需要指定 content-type:application/json5.2重定向(1)重定向到百度# 重定向@('/demo')def demo(): return redirect('')(2)重定向到⾃⼰写的视图函数直接填写⾃⼰ url 路径使⽤ url_for ⽣成指定视图函数所对应的 url@('/demo1')def demo1(): return 'demo1'# 重定向,采⽤url_for⽣成demo1对应的url@('/demo2')def demo2(): return redirect(url_for('demo1'))(3)重定向到带有参数的视图函数# 路由传递参数@('/user/')def user_info(user_id): return 'hello %d' % user_id# 重定向,在url_for中传⼊参数@('/demo5')def demo5(): # 使⽤ url_for ⽣成指定视图函数所对应的 url return redirect(url_for('user_info', user_id=100))5.3⾃定义状态码⾃定义不符合 http 协议的状态码@('/demo')def demo(): return '状态码为 666', 6666、异常捕获6.1 HTTP主动抛出异常abort ⽅法抛出⼀个给定状态代码的 HTTPException 或者 指定响应,例如想要⽤⼀个页⾯未找到异常来终⽌请求,你可以调⽤ abort(404)。参数:code – HTTP的错误状态码# abort(404)# 抛出状态码的话,只能抛出 HTTP 协议的错误状态码abort(500)6.2捕获错误errorhandler 装饰器注册⼀个错误处理程序,当程序抛出指定错误状态码的时候,就会调⽤该装饰器所装饰的⽅法参数:code_or_exception – HTTP的错误状态码或指定异常例如统⼀处理状态码为500的错误给⽤户友好的提⽰:# 处理所有500类型的异常@andler(500)def internal_server_error(e): return '服务器搬家了'# 处理特定的异常项@andler(ZeroDivisionError)def zero_division_error(e): return '除数不能为0' 7、勾⼦函数在客户端和服务器交互的过程中,有些准备⼯作或扫尾⼯作需要处理,⽐如:在请求开始时,建⽴数据库连接;在请求开始时,根据需求进⾏权限校验;在请求结束时,指定数据的交互格式;为了让每个视图函数避免编写重复功能的代码,Flask提供了通⽤设施的功能,即请求钩⼦。请求钩⼦是通过装饰器的形式实现,Flask⽀持如下四种请求钩⼦:before_first_request在处理第⼀个请求前执⾏before_request在每次请求前执⾏如果在某修饰的函数中返回了⼀个响应,视图函数将不再被调⽤after_request如果没有抛出错误,在每次请求后执⾏接受⼀个参数:视图函数作出的响应在此函数中可以对响应值在返回之前做最后⼀步修改处理需要将参数中的响应在此参数中进⾏返回teardown_request:在每次请求后执⾏接受⼀个参数:错误信息,如果有相关错误抛出from flask import Flaskfrom flask import abortapp = Flask(__name__)# 在第⼀次请求之前调⽤,可以在此⽅法内部做⼀些初始化操作@_first_requestdef before_first_request(): print("before_first_request")# 在每⼀次请求之前调⽤,这时候已经有请求了,可能在这个⽅法⾥⾯做请求的校验# 如果请求的校验不成功,可以直接在此⽅法中进⾏响应,直接return之后那么就不会执⾏视图函数@_requestdef before_request(): print("before_request") # if 请求不符合条件: # return "laowang"# 在执⾏完视图函数之后会调⽤,并且会把视图函数所⽣成的响应传⼊,可以在此⽅法中对响应做最后⼀步统⼀的处理@_requestdef after_request(response): print("after_request") s["Content-Type"] = "application/json" return response# 请每⼀次请求之后都会调⽤,会接受⼀个参数,参数是服务器出现的错误信息@wn_requestdef teardown_request(e): print("teardown_request")@('/')def index(): return 'index'if __name__ == '__main__': (debug=True)执⾏结果在第1次请求时的打印:before_first_requestbefore_requestafter_requestteardown_request在第2次请求时的打印:before_requestafter_requestteardown_request 8. request请求参数  request 就是flask中代表当前请求的 request 对象,作为请求上下⽂变量(理解成全局变量,在视图函数中直接使⽤可以取到当前本次请求)  常⽤属性: 属性dataformargscookiesheadersmethodurlfiles

说明记录请求的数据,并转换为字符串记录请求中的表单数据记录请求中的查询参数记录请求中的cookie信息记录请求中的报⽂头记录请求使⽤的HTTP⽅法记录请求的URL地址记录请求上传的⽂件类型*MultiDictMultiDictDictEnvironHeadersGET/POSTstring*

# 获取上传的图⽚并保存到本地@('/', methods=['POST'])def index(): pic = ('pic') ('./static/') return 'index'9、flask上下⽂参数  上下⽂:相当于⼀个容器,保存了 Flask 程序运⾏过程中的⼀些信息。  Flask中有两种上下⽂,请求上下⽂(request context)和应⽤上下⽂(application context)1. application 指的就是当你调⽤app = Flask(__name__)创建的这个对象app;2. request 指的是每次http请求发⽣时,WSGI server(⽐如gunicorn)调⽤Flask.__call__()之后,在Flask对象内部创建的Request对象;3. application 表⽰⽤于响应WSGI请求的应⽤本⾝,request 表⽰每次http请求;4. application的⽣命周期⼤于request,⼀个application存活期间,可能发⽣多次http请求,所以,也就会有多个request  源码了解⼀下 flask

如何实现这两种context: # 代码摘选⾃flask 0.5 中的⽂件, 进⾏了部分删减class _RequestContext(object):

def __init__(self, app, environ): = app t = t_class(environ) n = _session(t) self.g = _RequestGlobals()# flask 使⽤_RequestContext的代码如下:class Flask(object): def request_context(self, environ): return _RequestContext(self, environ)在Flask类中,每次请求都会调⽤这个request_context函数。这个函数则会创建⼀个_RequestContext对象。这个对象在创建时,将Flask实例的本⾝作为实参传⼊_RequestContext⾃⾝,因此, = Flask()。所以,虽然每次http请求都会创建⼀个_RequestContext对象,但是,每次创建的时候都会将同⼀个Flask对象传⼊该对象的app成员变量,使得:由同⼀个Flask对象响应的请求所创建的_RequestContext对象的app成员变量都共享同⼀个application通过在Flask对象中创建_RequestContext对象,并将Flask⾃⾝作为参数传⼊_RequestContext对象的⽅式,实现了多个request context对应⼀个applicationcontext 的⽬的。  (1)请求上下⽂(request context)  请求上下⽂对象有:request、sessionrequest封装了HTTP请求的内容,针对的是http请求。举例:user = ('user'),获取的是get请求的参数。session⽤来记录请求会话中的信息,针对的是⽤户信息。举例:session['name'] = ,可以记录⽤户信息。还可以通过('name')获取⽤户信息。(2)应⽤上下⽂(application context)  应⽤上下⽂对象有:current_app,g  ①current_app  应⽤程序上下⽂,⽤于存储应⽤程序中的变量,可以通过current_打印当前app的名称,也可以在current_app中存储⼀些变量,例如:应⽤的启动脚本是哪个⽂件,启动时指定了哪些参数加载了哪些配置⽂件,导⼊了哪些配置连了哪个数据库有哪些public的⼯具类、常量应⽤跑再哪个机器上,IP多少,内存多⼤current_rrent__value='value'  ②g变量  g 作为 flask 程序全局的⼀个临时变量,充当中间媒介的作⽤,我们可以通过它传递⼀些数据,g 保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别 ='zhangsan'请求上下⽂:保存了客户端和服务器交互的数据应⽤上下⽂:flask 应⽤程序运⾏过程中,保存的⼀些配置信息,⽐如程序名、数据库连接、应⽤信息等使⽤Cookie:指某些⽹站为了辨别⽤户⾝份、进⾏会话跟踪⽽储存在⽤户本地的数据(通常经过加密)。复数形式Cookies。Cookie是由服务器端⽣成,发送给客户端浏览器,浏览器会将Cookie的key/value保存,下次请求同⼀⽹站时就发送该Cookie给服务器(前提是浏览器设置为启⽤cookie)。Cookie的key/value可以由服务器端⾃⼰定义。# 设置cookie# 当浏览器请求某⽹站时,会将本⽹站下所有Cookie信息提交给服务器,所以在request中可以读取Cookie信息from flask imoprt Flask, make_response@('/cookie')def set_cookie(): resp = make_response('this is to set cookie') _cookie('username', 'zhangsan') _cookie("pwd", "12321")   return resp# 设置过期时间@('/cookie')def set_cookie(): response = make_response('hello world') _cookie('username', 'zhangsan', max_age=3600) # 过期时间为3600秒 return response# 获取cookiefrom flask import Flask, request@('/request')def resp_cookie(): resp = ('username') return resp# 删除cookie@("/logout")def logout(): resp = make_response("success") _cookie("username") _cookie("pwd") return resp11、Session使⽤# session数据的获取# session:请求上下⽂对象,⽤于处理http请求中的⼀些数据内容# 设置secret_key# 作⽤:设置⼀个secret_key值,⽤作各种 _key = 'python'# 考虑到安全性, 这个密钥不建议存储在程序中. 最好的⽅法是存储在你的系统环境变量中, 通过 (key, default=None) 获得.

#设置session,并重定向到获取session的index函数@("/login")def login(): session["username"] = 'zhangsan' session['password'] = "1234321" return redirect(url_for("index"))# 获取session@("/")def index(): username = ("username") password = ("password") return "世界真美好%s======%s" % (username, password)# 删除session,并重定向到获取session的index函数@("/logout")def logout(): ("username") ("password") return redirect(url_for("index"))12、蓝图BlueprintBlueprint 是⼀个存储操作⽅法的容器,这些操作在这个Blueprint 被注册到⼀个应⽤之后就可以被调⽤,Flask 可以通过Blueprint来组织URL以及处理请求。Flask使⽤Blueprint让应⽤实现模块化,在Flask中,Blueprint具有如下属性:⼀个应⽤可以具有多个Blueprint可以将⼀个Blueprint注册到任何⼀个未使⽤的URL下⽐如 “/”、“/sample”或者⼦域名在⼀个应⽤中,⼀个模块可以注册多次Blueprint可以单独具有⾃⼰的模板、静态⽂件或者其它的通⽤操作⽅法,它并不是必须要实现应⽤的视图和函数的在⼀个应⽤初始化时,就应该要注册需要使⽤的Blueprint但是⼀个Blueprint并不是⼀个完整的应⽤,它不能独⽴于应⽤运⾏,⽽必须要注册到某⼀个应⽤中。蓝图/Blueprint对象⽤起来和⼀个应⽤/Flask对象差不多,最⼤的区别在于⼀个 蓝图对象没有办法独⽴运⾏,必须将它注册到⼀个应⽤对象上才能⽣效使⽤蓝图可以分为三个步骤1,创建⼀个蓝图对象admin=Blueprint('admin',__name__)2,在这个蓝图对象上进⾏操作,注册路由,指定静态⽂件夹,注册模版过滤器@('/admin')def index(): return 'admin_home'3,在应⽤对象上注册这个蓝图对象er_blueprint(admin,url_prefix='/admin')当这个应⽤启动后,通过/admin/admin/可以访问到蓝图中定义的视图函数运⾏机制蓝图是保存了⼀组将来可以在应⽤对象上执⾏的操作,注册路由就是⼀种操作当在应⽤对象上调⽤ route 装饰器注册路由时,这个操作将修改对象的url_map路由表然⽽,蓝图对象根本没有路由表,当我们在蓝图对象上调⽤route装饰器注册路由时,它只是在内部的⼀个延迟操作记录列表defered_functions中添加了⼀个项当执⾏应⽤对象的 register_blueprint() ⽅法时,应⽤对象将从蓝图对象的 defered_functions 列表中取出每⼀项,并以⾃⾝作为参数执⾏该匿名函数,即调⽤应⽤对象的 add_url_rule() ⽅法,这将真正的修改应⽤对象的路由表蓝图的url前缀当我们在应⽤对象上注册⼀个蓝图时,可以指定⼀个url_prefix关键字参数(这个参数默认是/)在应⽤最终的路由表 url_map中,在蓝图上注册的路由URL⾃动被加上了这个前缀,这个可以保证在多个蓝图中使⽤相同的URL规则⽽不会最终引起冲突,只要在注册蓝图时将不同的蓝图挂接到不同的⾃路径即可url_forurl_for('') # /admin/admin/ 将admin下index函数路由注册

注册静态路由和应⽤对象不同,蓝图对象创建时不会默认注册静态⽬录的路由。需要我们在 创建时指定 static_folder 参数。下⾯的⽰例将蓝图所在⽬录下的static_admin⽬录设置为静态⽬录admin = Blueprint("admin",__name__,static_folder='static_admin')er_blueprint(admin,url_prefix='/admin')现在就可以使⽤/admin/static_admin/ 访问static_admin⽬录下的静态⽂件了 定制静态⽬录URL规则 :可以在创建蓝图对象时使⽤ static_url_path 来改变静态⽬录的路由。下⾯的⽰例将为 static_admin ⽂件夹的路由设置为 /libadmin = Blueprint("admin",__name__,static_folder='static_admin',static_url_path='/lib')er_blueprint(admin,url_prefix='/admin')设置模版⽬录蓝图对象默认的模板⽬录为系统的模版⽬录,可以在创建蓝图对象时使⽤ template_folder 关键字参数设置模板⽬录admin = Blueprint('admin',__name__,template_folder='my_templates')13、Flask-Script 扩展通过使⽤Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令⾏的⽅式传⼊参数。⽽不仅仅通过()⽅法中传参,⽐如我们可以通过:python runserver -host ip地址 -P 端⼝# 1 、安装 Flask-Script 扩展pip install flask-script# 2、集成 Flask-Scriptfrom flask import Flaskfrom flask_script import Managerapp = Flask(__name__)# 把 Manager 类和应⽤程序实例进⾏关联manager = Manager(app)@('/')def index(): return 'hello world'if __name__ == "__main__": ()

发布者:admin,转转请注明出处:http://www.yc00.com/web/1688420705a135764.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信