Python Web框架学习【Flask】
flask 是利用Python编写的轻量级Web应用框架Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。其 WSGI 工具箱采用 Werkzeug 模板引擎则使用 Jinja2 Flask使用 BSD 授权
WSGI(PythonWeb服务器网关接口)Python Web Server Gateway Interface
Python应用程序或框架和Web服务器之间的一种接口
BSD开源协议一个给于使用者很大自由的协议,BSD 代码鼓励代码共享,但需要尊重代码作者的著作权。
利用flask实现一个最小应用
创建一个.py文件(test.py),添加代码如下:
# 导入Flask类,该类的实例将作为我们的WSGI应用from flask import Flask# 实例化Flask类,第一个参数应当是包或者模块名,单一模块使用__name__即可app = Flask(__name__)# route装饰器用于确定触发函数的url@app.route('/')def index():# 函数的返回值为用户在浏览器中获取的值 return 'Hello World'
运行可以直接在代码中调用run方法,然后执行该.py文件即可
app.run(host='0.0.0.0', port=5000) # 0.0.0.0开放所有ip,port用于指定端口# host指定开放ip,port指定端口号,默认127.0.0.1(回环地址)5000端口
或者在命令行中导出环境变量,然后执行
export FLASK_APP=test.py # 非当前目录下须添加绝对路径flask run # 运行
此时利用浏览器访问ip+端口(如127.0.0.1:5000),可以看到Helloworld字符注意在浏览器访问时,ip后须加端口号,如果不加,默认使用http服务(80端口)
设置路由
web应用使用有意义的url,有助于用户理解记忆,提高用户体验例如: 百度主页:www.baidu.com 百度新闻:news.baidu.com 百度贴吧:tieba.baidu.com上面我们用到的route装饰器就是用来绑定url和函数例如下面这一段表示,用户访问ip/时触发的函数为index
@app.route('/')def index(): return 'Hello World'
此外,还可以动态变化url利用<variable_name> 的方式,将url的一部分标记为变量,并传递给函数
@app.route('/<username>')def user(): return 'Hello %s'%username # 根据url变量部分返回字符串
还可以利用<converter:variable_name>,选择转换器,为变量指定规则
@app.route('/<int:username>') # 指定变量为整型def user(): return 'Hello %s'%username
模板渲染
当我们需要向用户返回一个完善的html页面时如果将html源码全部贴在return后面显然会让人头疼Flask自动为我们配置Jinja2模板引擎我们可以利用render_template调用模板,并传入参数进行渲染
@app.route('/user/')def user(): username = 'testUser' # 测试数据 return render_template('user.html',user=username)
第一个参数为需要调用的html模板,后面传入关键字参数在html中利用关键字访问数据render_template默认会从当前目录下的templates文件夹中寻找模板
user.html中添加一个p标签,利用‘{{user}}‘的形式显示user参数的值
利用浏览器访问
模板继承
大多情况下,同一个域名下的各个子页面风格大致相同,具有相同的框架比如同样的导航栏,底部等等为避免重复工作,可以制作一个共用的基础模板,然后通过模板继承来实现共用框架
基础模板
基模板(base.html)中写好了头部和尾部,在身体部分放置了可以重载的块
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><h2 >我是模板头部</h2>{% block body %}<p>可重载部分</p>{% endblock %}<h2 >我是模板尾部</h2></body></html>
子模板(use_base.html)
{% extends "base.html" %} <--! 扩展了基础模板 -->{% block body %}<p > 这是子模板新加入的内容</p>{% endblock %}
访问页面
如果需要在子模板中调用父模板,需要在block中使用{{ super() }}
请求对象
首先导入请求对象 from flask import Flask通过使用 method 属性可以操作当前请求方法通过使用 form 属性处理表单数据(在 POST 或者 PUT 请求 中传输的数据)在.py文件中添加代码如下:
@app.route('/login/',methods=['POST','GET']) # methods默认只支持GETdef login(): # 当请求的方法为POST时 if request.method=='POST': # 通过form表单获取提交的数据 un = request.form['username'] pw = request.form['password'] # 判断用户名密码是否正确 if un =='root' and pw =='redhat': # 正确返回登录成功 return '登录成功' else: # 错误返回登录页面并提示 return render_template('login.html',error='用户名或密码错误') # 请求方法不为POST时,返回登录页面 return render_template('login.html')
在form 表单中利用input提交信息,并指定key值(username/password)编写好一个简易的登录页面,如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><form action="/login/" method="post"> <--! 以post的方式提交表单--> <input type="text" placeholder="请输入用户名" name="username"> <input type="password" placeholder="请输入密码" name="password"> <input type="submit" value="登录"> <p >{{error}}</p> <--! 登录失败时显示错误信息 --> </form></body></html>
登录页面
如果需要对Url中传递的参数(例如ip?key=value)进行操作可以使用request.args.get('key')
文件上传
用 Flask 处理文件上传很容易记得要在html页面中设置表单 enctype="multipart/form-data" 属性否则浏览器将不会传送你的文件在获取原文件名时可以使用filename属性,但该值可以伪造,不可信想要把客户端上源文件名作服务器上的文件名时可以使用Werkzeug 提供的secure_filename()函数需要导入 from werkzeug.utils import secure_filename在.py文件中添加代码如下:
from werkzeug.utils import secure_filename@app.route('/upload/',methods=['POST','GET'])def upload(): # 当请求方法为POST的时 if request.method == 'POST': # 读取上传的文件 try: filename=None f = request.files['file_upload'] # 获取文件名 filename = secure_filename(f.filename) # 保存文件到doc下 f.save('doc/%s'%filename) except: # 未获取到文件提示上传失败 return render_template('upload.html',error='上传失败') # 返回上传界面,传递文件名 return render_template('upload.html',filename=filename) # 返回上传界面 return render_template('upload.html')
编写一个简易的上传html界面如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><!-- 上传文件 --><form action="/upload/" enctype="multipart/form-data" method="post"> <input type="file" placeholder="未选择文件" name="file_upload"> <input type="submit" value="提交文件"> <!--当文件上传成功时,显示提交成功--> {% if filename %} <p >{{ filename }}提交成功</p> {% endif%} <!--未上传显示失败--> <p >{{ error }}</p></form></body></html>
上传界面
重定向和错误
使用 redirect() 函数可以重定向使用 abort() 可以 更早退出请求,并返回错误代码需要从flask中导入 from flask import abort,redirect在.py文件中添加代码如下:
@app.route('/error/')def error(): abort(401) # 退出并返回一个401错误页面@app.route('/redirect/')def direct(): return redirect('/') # 重定向至/下(显示Helloworld)
返回错误页面
我们还可以使用 errorhandler() 装饰器可以定制出错页面,在.py中添加代码如下:
# 定制401出错界面为指定html 'error401.html'@app.errorhandler(401)def forbidden(): return render_template('error401.html')
编写一个简易401html错误界面如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><h2>这是一个401错误页面</h2></body></html>
新的自定义401错误页面
响应对象
视图函数(即被route装饰器装饰的函数)的返回值 会自动转换为一个响应对象
转换规则:
如果视图返回的是一个响应对象,那么就直接返回它。如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的 响应对象。如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中必须至少 包含一个项目,且项目应当由 (response, status, headers) 或者 (response, headers) 组成。 status 的值会重载状态代码, headers 是一个由额外头部值组成的列表或字典。如果以上都不是,那么 Flask 会假定返回值是一个有效的 WSGI 应用并把它转换为 一个响应对象。
如果想要在视图函数内部获取响应对象的结果,可以使用make_response()函数
参考资料官方中文文档
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。