python-flask,flask框架介绍
Flask是基于Python,依托jinja2模板和WerkzeugWSGI服务开发的微框架。Werkzeug本质上是一个Socket服务器,用来接收http请求并进行预处理,然后触发flask框架。本文介绍了Python中的Flask框架,感兴趣的朋友可以跟着边肖看看。
Flask是一个用Python编写的web微框架,它允许我们使用Python语言快速实现一个网站或Web服务。本文参考Flask的官方文档,大部分代码引用自官方文档。
安装flask
首先,让我们安装烧瓶。最简单的方法是使用pip。
pip安装烧瓶
然后打开一个Python文件,输入以下内容并运行该文件。然后访问localhost:5000,我们应该在浏览器上看到hello world输出。
从烧瓶进口烧瓶
app=Flask(__name__)
@app.route(/)
def hello_world():
返回“hello world”
if __name__==__main__:
app.run(主机=127.0.0.1 ,端口=5000)
调试模式
我们修改代码中的输出,然后查看浏览器上是否有任何变化。如果你这样做,你可以看到什么都没有改变。其实Flask内置了调试模式,可以自动重新加载代码,显示调试信息。这需要我们打开调试模式。方法很简单。设置FLASK_DEBUG环境变量,并将该值设置为1。或者设置app.debug=True。
从烧瓶进口烧瓶
app=Flask(__name__)
app.debug=True
@app.route(/)
def hello_world():
返回“你好,世界!”
@app.route(/login )
定义登录():
返回“登录”
if __name__==__main__:
app.run()
然后再次运行该程序,您将看到以下输出。这时,如果你再次修改代码,你会发现这次Flask会自动重启。
*用stat重启
*调试器处于活动状态!
*调试器PIN: 157-063-180
*运行于http://127.0.0.1:5000/(按CTRL C退出)
路由
你可以在上面的例子中看到路由的使用。如果你了解Spring Web MVC,你应该对路由很熟悉。通过使用Flask的app.route decorator设置路由,这与Java注释类似。
@app.route(/)
定义索引():
返回“索引页”
@app.route(/hello )
def hello():
回复“你好,世界”
路径变量
如果想得到/article/1这样的路径参数,就需要使用路径变量。变量的语法是/path/converter:varname。在path变量之前也可以使用可选的转换器。有以下转换器。
使用string作为转换器的默认选项,接受string int除斜杠接受整数float接受浮点数路径类似于string,但是接受string带斜杠任意匹配任意转换器uuid接受UUID string这里是Flask的官方例子。
@ app . route(/用户/用户名)
定义显示用户配置文件(用户名):
#显示该用户的用户配置文件
return User %s % username
@app.route(/post/<int:post_id>)
def show_post(post_id):
# show the post with the given id, the id is an integer
return Post %d % post_id
构造URL
在Web程序中常常需要获取某个页面的URL,在Flask中需要使用url_for('方法名')
来构造对应方法的URL。下面是Flask官方的例子。
>>> from flask import Flask, url_for>>> app = Flask(__name__)
>>> @app.route(/)
... def index(): pass
...
>>> @app.route(/login)
... def login(): pass
...
>>> @app.route(/user/<username>)
... def profile(username): pass
...
>>> with app.test_request_context():
... print url_for(index)
... print url_for(login)
... print url_for(login, next=/)
... print url_for(profile, username=John Doe)
...
/
/login
/login?next=/
/user/John%20Doe
HTTP方法
如果需要处理具体的HTTP方法,在Flask中也很容易,使用route
装饰器的methods
参数设置即可。
from flask import request@app.route(/login, methods=[GET, POST])
def login():
if request.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
函数并传入模板文件名和参数名即可。
from flask import render_template@app.route(/hello/)
@app.route(/hello/<name>)
def hello(name=None):
return render_template(hello.html, name=name)
相应的模板文件如下。
<!doctype html><title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
日志输出
Flask 为我们预配置了一个 Logger,我们可以直接在程序中使用。这个Logger是一个标准的Python Logger,所以我们可以向标准Logger那样配置它,详情可以参考官方文档或者我的文章Python 日志输出。
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
处理请求
在 Flask 中获取请求参数需要使用request
等几个全局对象,但是这几个全局对象比较特殊,它们是 Context Locals ,其实就是 Web 上下文中局部变量的代理。虽然我们在程序中使用的是全局变量,但是对于每个请求作用域,它们都是互不相同的变量。理解了这一点,后面就非常简单了。
Request 对象
Request 对象是一个全局对象,利用它的属性和方法,我们可以方便的获取从页面传递过来的参数。
method
属性会返回HTTP方法的类似,例如post
和get
。form
属性是一个字典,如果数据是POST类型的表单,就可以从form
属性中获取。下面是 Flask 官方的例子,演示了 Request 对象的method
和form
属性。
from flask import request@app.route(/login, methods=[POST, GET])
def login():
error = None
if request.method == POST:
if valid_login(request.form[username],
request.form[password]):
return log_the_user_in(request.form[username])
else:
error = Invalid username/password
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template(login.html, error=error)
如果数据是由GET方法传送过来的,可以使用args
属性获取,这个属性也是一个字典。
searchword = request.args.get(key, )
文件上传
利用Flask也可以方便的获取表单中上传的文件,只需要利用 request 的files
属性即可,这也是一个字典,包含了被上传的文件。如果想获取上传的文件名,可以使用filename
属性,不过需要注意这个属性可以被客户端更改,所以并不可靠。更好的办法是利用werkzeug
提供的secure_filename
方法来获取安全的文件名。
from flask import requestfrom werkzeug.utils import secure_filename
@app.route(/upload, methods=[GET, POST])
def upload_file():
if request.method == POST:
f = request.files[the_file]
f.save(/var/www/uploads/ + secure_filename(f.filename))
Cookies
Flask也可以方便的处理Cookie。使用方法很简单,直接看官方的例子就行了。下面的例子是如何获取cookie。
from flask import request@app.route(/)
def index():
username = request.cookies.get(username)
# 使用 cookies.get(key) 代替 cookies[key] 避免
# 得到 KeyError 如果cookie不存在
如果需要发送cookie给客户端,参考下面的例子。
from flask import make_response@app.route(/)
def index():
resp = make_response(render_template(...))
resp.set_cookie(username, the username)
return resp
重定向和错误
redirect
和abort
函数用于重定向和返回错误页面。
from flask import abort, redirect, url_for@app.route(/)
def index():
return redirect(url_for(login))
@app.route(/login)
def login():
abort(401)
this_is_never_executed()
默认的错误页面是一个空页面,如果需要自定义错误页面,可以使用errorhandler
装饰器。
from flask import render_template@app.errorhandler(404)
def page_not_found(error):
return render_template(page_not_found.html), 404
响应处理
默认情况下,Flask会根据函数的返回值自动决定如何处理响应:如果返回值是响应对象,则直接传递给客户端;如果返回值是字符串,那么就会将字符串转换为合适的响应对象。我们也可以自己决定如何设置响应对象,方法也很简单,使用make_response
函数即可。
@app.errorhandler(404)def not_found(error):
resp = make_response(render_template(error.html), 404)
resp.headers[X-Something] = A value
return resp
Sessions
我们可以使用全局对象session
来管理用户会话。Sesison 是建立在 Cookie 技术上的,不过在 Flask 中,我们还可以为 Session 指定密钥,这样存储在 Cookie 中的信息就会被加密,从而更加安全。直接看 Flask 官方的例子吧。
from flask import Flask, session, redirect, url_for, escape, requestapp = Flask(__name__)
@app.route(/)
def index():
if username in session:
return Logged in as %s % escape(session[username])
return You are not logged in
@app.route(/login, methods=[GET, POST])
def login():
if request.method == POST:
session[username] = request.form[username]
return redirect(url_for(index))
return
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
@app.route(/logout)
def logout():
# remove the username from the session if its there
session.pop(username, None)
return redirect(url_for(index))
# set the secret key. keep this really secret:
app.secret_key = A0Zr98j/3yX R~XHH!jmN]LWX/,?RT
模板简介
这里简单的介绍一下Jinja 模板的使用方法,详细资料直接看原文档吧。
模板标签
其实Jinja 模板和其他语言和框架的模板类似,反正都是通过某种语法将HTML文件中的特定元素替换为实际的值。如果使用过JSP、Thymeleaf 等模板,应该可以非常容易的学会使用 Jinja模板。
其实从上面的例子中我们应该可以看到Jinja 模板的基本语法了。代码块需要包含在{% %}
块中,例如下面的代码。
{% extends layout.html %}{% block title %}主页{% endblock %}
{% block body %}
<div class="jumbotron">
<h1>主页</h1>
</div>
{% endblock %}
双大括号中的内容不会被转义,所有内容都会原样输出,它常常和其他辅助函数一起使用。下面是一个例子。
<a class="navbar-brand" href={{ url_for(index) }}>Flask小例子</a>
继承
模板可以继承其他模板,我们可以将布局设置为父模板,让其他模板继承,这样可以非常方便的控制整个程序的外观。
例如这里有一个layout.html
模板,它是整个程序的布局文件。
<!DOCTYPE html><html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for(static,filename=css/bootstrap.css) }}" rel="external nofollow" />
<link rel="stylesheet" href="{{ url_for(static,filename=css/bootstrap-theme.css) }}" rel="external nofollow" />
</head>
<body>
<div class="container body-content">
{% block body %}{% endblock %}
</div>
<div class="container footer">
<hr>
<p>这是页脚</p>
<script src="{{ url_for(static,filename=js/jquery.js) }}"></script>
<script src="{{ url_for(static,filename=js/bootstrap.js) }}"></script>
</body>
</html>
其他模板可以这么写。对比一下面向对象编程的继承概念,我们可以很容易的理解。
{% extends layout.html %}{% block title %}主页{% endblock %}
{% block body %}
<div class="jumbotron">
<h1>主页</h1>
<p>本项目演示了Flask的简单使用方法,点击导航栏上的菜单条查看具体功能。</p>
</div>
{% endblock %}
控制流
条件判断可以这么写,类似于JSP标签中的Java 代码,{% %}
中也可以写Python代码。下面是Flask官方文档的例子。
<div class=metanav>{% if not session.logged_in %}
<a href="{{ url_for(login) }}" rel="external nofollow" >log in</a>
{% else %}
<a href="{{ url_for(logout) }}" rel="external nofollow" >log out</a>
{% endif %}
</div>
循环的话可以这么写,和在Python中遍历差不多。
<tbody>{% for key,value in data.items() %}
<tr>
<td>{{ key }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
<tr>
<td>文件</td>
<td></td>
</tr>
</tbody>
需要注意不是所有的Python代码都可以写在模板里,如果希望从模板中引用其他文件的函数,需要显式将函数注册到模板中。可以参考这个爆栈提问。
写在最后
这篇文章主要参考了Flask的官方文档,但是只介绍了 Flask的最基本的一部分。了解了这部分,我们可以用Python 搭一个小服务器做点事情。如果希望详细了解 Flask的使用用法,请关注更详细的资料。本文就是起一个抛砖引玉的效果。
顺便说,通过Flask 我也了解了Python 语言的执行速度。我们都知道编译器编译出来的代码执行起来要比解释器解释代码要快大约几十倍到几千倍不等。以前学Java的时候,感觉Java 慢,主要原因就是等待编译时间比较长。相对来说用Python写脚本就很块了,因为没有编译过程。
但是从Flask的运行速度来看,我切身感受到了Python 执行确实不快。举个例子,在Spring中写一个控制器,接受HTTP参数,并显示到页面上,如果程序编译完之后,这个显示过程基本是瞬时的。但是同样的需求在Flask中,我居然可以感觉到明显的延迟(大概几百毫秒的等待时间)。所以,如果你想写一个比较快的Web程序,还是用Java或者JVM语言吧,虽然看着土,性能确实杠杠的 。
到此这篇关于Python中的flask框架详解的文章就介绍到这了,更多相关Python flask框架内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。