这篇文章主要介绍关于flask的简介及案例分析,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

安装Flask

首先我们来安装Flask。最简单的办法就是使用pip。

pipinstallflask

然后打开一个Python文件,输入下面的内容并运行该文件。然后访问localhost:5000,我们可以可以看到浏览器上输出了Hello Flask!

fromflaskimportFlaskapp=Flask(__name__)@app.route('/')defhello_world():return'HelloFlask!'if__name__=='__main__':app.run()快速开始调试模式

我们修改代码中的输出,然后查看浏览器上是否有变化。如果你照做的话,可以看到什么变化都没有。其实Flask内置了调试模式,可以自动重载代码并显示调试信息。这需要我们开启调试模式,方法很简单,设置FLASK_DEBUG环境变量,链接值设置为1

然后再次运行程序,会看到有这样的输出。这时候如果再次修改代码,会发现这次Flask会自动重启。

*Restartingwithstat*Debuggerisactive!*DebuggerPIN:157-063-180*Runningonhttp://127.0.0.1:5000/(PressCTRL+Ctoquit)路由

如果了解Spring Web MVC的话,应该对路由很熟悉。路由通过使用Flask的app.route装饰器来设置,这类似Java的注解。

@app.route('/')defindex():return'IndexPage'@app.route('/hello')defhello():return'Hello,World'路径变量

如果希望获取/article/1这样的路径参数,就需要使用路径变量。路径变量的语法是/path/<converter:varname>。在路径变量前还可以使用可选的转换器,有以下几种转换器。

转换器作用string默认选项,接受除了斜杠之外的字符串int接受整数float接受浮点数path和string类似,不过可以接受带斜杠的字符串any匹配任何一种转换器uuid接受UUID字符串

下面是Flask官方的例子。

@app.route('/user/<username>')defshow_user_profile(username):#showtheuserprofileforthatuserreturn'User%s'%username@app.route('/post/<int:post_id>')defshow_post(post_id):#showthepostwiththegivenid,theidisanintegerreturn'Post%d'%post_id构造URL

在Web程序中常常需要获取某个页面的URL,在Flask中需要使用url_for('方法名')来构造对应方法的URL。下面是Flask官方的例子。

>>>fromflaskimportFlask,url_for>>>app=Flask(__name__)>>>@app.route('/')...defindex():pass...>>>@app.route('/login')...deflogin():pass...>>>@app.route('/user/<username>')...defprofile(username):pass...>>>withapp.test_request_context():...printurl_for('index')...printurl_for('login')...printurl_for('login',next='/')...printurl_for('profile',username='JohnDoe')...//login/login?next=//user/John%20DoeHTTP方法

如果需要处理具体的HTTP方法,在Flask中也很容易,使用route装饰器的methods参数设置即可。

fromflaskimportrequest@app.route('/login',methods=['GET','POST'])deflogin():ifrequest.method=='POST':do_the_login()else:show_the_login_form()静态文件

Web程序中常常需要处理静态文件,在Flask中需要使用url_for函数并指定static端点名和文件名。在下面的例子中,实际的文件应放在static/文件夹下。

url_for('static',filename='style.css')模板生成

Flask默认使用Jinja2作为模板,Flask会自动配置Jinja 模板,所以我们不需要其他配置了。默认情况下,模板文件需要放在templates文件夹下。

使用 Jinja 模板,只需要使用render_template函数并传入模板文件名和参数名即可。

fromflaskimportrender_template@app.route('/hello/')@app.route('/hello/<name>')defhello(name=None):returnrender_template('hello.html',name=name)

相应的模板文件如下。

<!doctypehtml><title>HellofromFlask</title>{%ifname%}<h2>Hello{{name}}!</h2>{%else%}<h2>Hello,World!</h2>{%endif%}日志输出

Flask 为我们预配置了一个 Logger,我们可以直接在程序中使用。这个Logger是一个标准的Python Logger,所以我们可以向标准Logger那样配置它,详情可以参考官方文档或者我的文章Python 日志输出。

app.logger.debug('Avaluefordebugging')app.logger.warning('Awarningoccurred(%dapples)',42)app.logger.error('Anerroroccurred')处理请求

在 Flask 中获取请求参数需要使用request等几个全局对象,但是这几个全局对象比较特殊,它们是 Context Locals ,其实就是 Web 上下文中局部变量的代理。虽然我们在程序中使用的是全局变量,但是对于每个请求作用域,它们都是互不相同的变量。理解了这一点,后面就非常简单了。

Request 对象

Request 对象是一个全局对象,利用它的属性和方法,我们可以方便的获取从页面传递过来的参数。

method属性会返回HTTP方法的类似,例如postgetform属性是一个字典,如果数据是POST类型的表单,就可以从form属性中获取。下面是 Flask 官方的例子,演示了 Request 对象的methodform属性。

fromflaskimportrequest@app.route('/login',methods=['POST','GET'])deflogin():error=Noneifrequest.method=='POST':ifvalid_login(request.form['username'],request.form['password']):returnlog_the_user_in(request.form['username'])else:error='Invalidusername/password'#thecodebelowisexecutediftherequestmethod#wasGETorthecredentialswereinvalidreturnrender_template('login.html',error=error)

如果数据是由GET方法传送过来的,可以使用args属性获取,这个属性也是一个字典。

searchword=request.args.get('key','')文件上传

利用Flask也可以方便的获取表单中上传的文件,只需要利用 request 的files属性即可,这也是一个字典,包含了被上传的文件。如果想获取上传的文件名,可以使用filename属性,不过需要注意这个属性可以被客户端更改,所以并不可靠。更好的办法是利用werkzeug提供的secure_filename方法来获取安全的文件名。

fromflaskimportrequestfromwerkzeug.utilsimportsecure_filename@app.route('/upload',methods=['GET','POST'])defupload_file():ifrequest.method=='POST':f=request.files['the_file']f.save('/var/www/uploads/'+secure_filename(f.filename))Cookies

Flask也可以方便的处理Cookie。使用方法很简单,直接看官方的例子就行了。下面的例子是如何获取cookie。

fromflaskimportrequest@app.route('/')defindex():username=request.cookies.get('username')#使用cookies.get(key)代替cookies[key]避免#得到KeyError如果cookie不存在

如果需要发送cookie给客户端,参考下面的例子。

fromflaskimportmake_response@app.route('/')defindex():resp=make_response(render_template(...))resp.set_cookie('username','theusername')returnresp重定向和错误

redirectabort函数用于重定向和返回错误页面。

fromflaskimportabort,redirect,url_for@app.route('/')defindex():returnredirect(url_for('login'))@app.route('/login')deflogin():abort(401)this_is_never_executed()

默认的错误页面是一个空页面,如果需要自定义错误页面,可以使用errorhandler装饰器。

fromflaskimportrender_template@app.errorhandler(404)defpage_not_found(error):returnrender_template('page_not_found.html'),404响应处理

默认情况下,Flask会根据函数的返回值自动决定如何处理响应:如果返回值是响应对象,则直接传递给客户端;如果返回值是字符串,那么就会将字符串转换为合适的响应对象。我们也可以自己决定如何设置响应对象,方法也很简单,使用make_response函数即可。

@app.errorhandler(404)defnot_found(error):resp=make_response(render_template('error.html'),404)resp.headers['X-Something']='Avalue'returnrespSessions

我们可以使用全局对象session来管理用户会话。Sesison 是建立在 Cookie 技术上的,不过在 Flask 中,我们还可以为 Session 指定密钥,这样存储在 Cookie 中的信息就会被加密,从而更加安全。直接看 Flask 官方的例子吧。

fromflaskimportFlask,session,redirect,url_for,escape,requestapp=Flask(__name__)@app.route('/')defindex():if'username'insession:return'Loggedinas%s'%escape(session['username'])return'Youarenotloggedin'@app.route('/login',methods=['GET','POST'])deflogin():ifrequest.method=='POST':session['username']=request.form['username']returnredirect(url_for('index'))return'''<formmethod="post"><p><inputtype=textname=username><p><inputtype=submitvalue=Login></form>'''@app.route('/logout')deflogout():#removetheusernamefromthesessionifit'stheresession.pop('username',None)returnredirect(url_for('index'))#setthesecretkey.keepthisreallysecret:app.secret_key='A0Zr98j/3yXR~XHH!jmN]LWX/,?RT'模板简介

这里简单的介绍一下Jinja 模板的使用方法,详细资料直接看原文档吧。

模板标签

其实Jinja 模板和其他语言和框架的模板类似,反正都是通过某种语法将HTML文件中的特定元素替换为实际的值。如果使用过JSP、Thymeleaf 等模板,应该可以非常容易的学会使用 Jinja模板。

其实从上面的例子中我们应该可以看到Jinja 模板的基本语法了。代码块需要包含在{% %}块中,例如下面的代码。

{%extends'layout.html'%}{%blocktitle%}主页{%endblock%}{%blockbody%}<divclass="jumbotron"><h2>主页</h2></div>{%endblock%}

双大括号中的内容不会被转义,所有内容都会原样输出,它常常和其他辅助函数一起使用。下面是一个例子。

<aclass="navbar-brand"href={{url_for('index')}}>Flask小例子</a>继承

模板可以继承其他模板,我们可以将布局设置为父模板,让其他模板继承,这样可以非常方便的控制整个程序的外观。

例如这里有一个layout.html模板,它是整个程序的布局文件。

<!DOCTYPEhtml><html><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width,initial-scale=1"><title>{%blocktitle%}{%endblock%}</title><linkrel="stylesheet"href="{{url_for('static',filename='css/bootstrap.css')}}"/><linkrel="stylesheet"href="{{url_for('static',filename='css/bootstrap-theme.css')}}"/></head><body><divclass="containerbody-content">{%blockbody%}{%endblock%}</div><divclass="containerfooter"><hr><p>这是页脚</p></div><scriptsrc="{{url_for('static',filename='js/jquery.js')}}"></script><scriptsrc="{{url_for('static',filename='js/bootstrap.js')}}"></script></body></html>

其他模板可以这么写。对比一下面向对象编程的继承概念,我们可以很容易的理解。

{%extends'layout.html'%}{%blocktitle%}主页{%endblock%}{%blockbody%}<divclass="jumbotron"><h2>主页</h2><p>本项目演示了Flask的简单使用方法,点击导航栏上的菜单条查看具体功能。</p></div>{%endblock%}

控制流

条件判断可以这么写,类似于JSP标签中的Java 代码,{% %}中也可以写Python代码。下面是Flask官方文档的例子。

<divclass=metanav>{%ifnotsession.logged_in%}<ahref="{{url_for('login')}}">login</a>{%else%}<ahref="{{url_for('logout')}}">logout</a>{%endif%}</div>

循环的话可以这么写,和在Python中遍历差不多。

<tbody>{%forkey,valueindata.items()%}<tr><td>{{key}}</td><td>{{value}}</td></tr>{%endfor%}<tr><td>文件</td><td></td></tr></tbody>

需要注意不是所有的Python代码都可以写在模板里,如果希望从模板中引用其他文件的函数,需要显式将函数注册到模板中。可以参考这个爆栈提问。

写在最后

这篇文章主要参考了Flask的官方文档,但是只介绍了Flask的最基本的一部分。了解了这部分,我们可以使用Python搭一个小服务器做点事情。更详细的资料。此处就是起一个抛砖引玉的效果。

顺便说,通过Flask我也了解了Python语言的执行速度。我们都知道编译器编译出来的代码执行起来要比解释器解释代码要快大约几十倍到几千倍不等。以前学Java的时候,感觉Java慢,初步就是等待编译时间比较长。相对来说用Python写脚本就很块了,因为没有编译过程。

但是从Flask的运行速度来看,我切身意识到了Python执行确实不快。举个例子,在Spring中写一个控制器,接受HTTP参数,并显示到页面上,如果程序编译完之后,这个显示过程基本是瞬时的。但是同样的需求在Flask中,我居然可以感觉到明显的延迟(大概几百毫秒的等待时间)。所以,如果你想写一个比较快的Web程序,还是用Java或JVM语言吧,,虽然看着土,性能确实杠杠的。

最后,我写了一个小练习,试了试Flask的基本功能,如果有兴趣可以上我的Github查看代码。


以上是关于flask的简介及案例分析的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!