Flask学习

文章目录

  • Flask学习
  • 1.简介
  • 2.安装
  • 3.最小的应用
  • 4.路由
  • 5.变量规则
  • 6.URL构建
  • 7.HTTP方法
  • 8.文件存放
  • 9.渲染模板
  • 10.Request对象
  • 11.Cookie
  • 12.会话Session
  • 实例1.上传表单数据
  • 实例2.上传下载文件

代码仓库:https://github.com/LenkyAndrews/Flask-Learning

1.简介

Flask是目前十分流行的web框架,采用Python编程语言来实现相关功能。它被称为微框架(microframework),“微”是指Flask旨在保持代码简洁且易于扩展,Flask框架的主要特征是核心构成比较简单,但具有很强的扩展性和兼容性。

Flask主要包括WerkzeugJinja2两个核心函数库,它们分别负责业务处理和安全方面的功能,这些基础函数为web项目开发过程提供了丰富的基础组件。

2.安装

使用以下指令安装:

pip install flask

输入指令查看版本

import flask
print(flask.__version__)
# 2.0.1

3.最小的应用

# 导入Flask类库
from flask import Flask
# 创建应用实例
app = Flask(__name__)
# 视图函数(路由)
@app.route("/")
def hello_world():return "Hello, World!"
# 启动服务
if __name__ == '__main__':app.run(debug = True)
  1. 首先导入了 Flask类。

  2. 接着创建一个该类的实例。第一个参数是应用模块或者包的名称。 __name__ 是一个适用于大多数情况的快捷方式。

  3. 然后使用 route()装饰器来告诉 Flask 触发函数 的 URL 。

    app.route(rule, options)
    

    rule 参数表示与该函数的URL绑定
    options 是要转发给基础Rule对象的参数列表。

  4. 函数返回需要在浏览器中显示的信息。

保存为app.py,一般不要使用 flask.py 作为应用名称,这会与 Flask 本身发生冲突。服务启动默认使用5000端口,在浏览器中打开 http://127.0.0.1:5000/ ,可以看到 Hello World! 字样。

app.run(host, port, debug, options)
参数 说明 默认值
host 主机名,设置为“0.0.0.0”以使服务器在外部可用 127.0.0.1(localhost)
port 端口号 5000
debug 调试模式,代码更新会自动重启服务,提供一个调试器来跟踪应用程序中的错误 False
options 要转发到底层的Werkzeug服务器的参数

4.路由

现代Web框架使用路由技术来帮助用户记住应用程序URL。Flask中的route()装饰器用于将URL绑定到函数,例如:

@app.route('/hello')
def hello_world():return 'hello world'

URL /hello 规则绑定到hello_world()函数,如果访问http://localhost:5000/hello,hello_world()函数的输出将在浏览器中呈现。

5.变量规则

通过把 URL 的一部分标记为 <variable_name> 就可以在 URL 中添加变量,标记的部分会作为关键字参数传递给函数。

from flask import Flask
app = Flask(__name__)@app.route('/hello/<username>')
def hello(username):return f'Hello {username}!'if __name__ == '__main__':app.run(debug = True)

在上面的例子中,在浏览器中输入http://localhost:5000/hello/Kint,则Kint将作为参数提供给 hello()函数,即username的值为Kint。在浏览器中的输出如下

Hello Kint!

通过使用 <converter:variable_name> ,可以选择性的加上一个转换器,为变量指定规则。

转换器 说明
string (缺省值) 接受任何不包含斜杠的文本
int 接受正整数
float 接受正浮点数
path 类似 string ,但可以包含斜杠

完整示例:

from flask import Flask
from markupsafe import escapeapp = Flask(__name__)@app.route('/hello/<username>')
def hello(username):return f'Hello {username}!'@app.route('/post/<int:post_id>')
def show_post(post_id):return f'Post {post_id}'@app.route('/path/<path:path>')
def show_path(path):return f'path {escape(path)}'if __name__ == '__main__':app.run(debug=True)

在浏览器中输入http://localhost:5000/integer/56,输出如下

Integer: 56

在浏览器中输入http://localhost:5000/path/templates/index.html,输出如下

path: templates/index.html

6.URL构建

url_for()函数用于构建指定函数的 URL。它把函数名称作为第一个参数。它可以接受任意个关键字参数,每个关键字参数对应 URL 中的变量,未知变量 将添加到 URL 中作为查询参数。

from flask import Flask, request, redirect
from flask import url_forapp = Flask(__name__)@app.route('/')
def index():return 'index'@app.route('/login')
def login():print(f"in login function, request.values: {request.values}")return 'login'@app.route('/user/<username>')
def profile(username):return f'{username}\'s profile'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'))

url_for('login', next='/')会生成对应的URL,但next并不是login函数的关键字参数,故作为查询参数,与GET请求发送的数据类似,可以在request.values中查询到CombinedMultiDict([ImmutableMultiDict([('next', '/')])])

输出如下:

/
/login
/login?next=%2F
/user/John%20Doe

7.HTTP方法

Web 应用使用不同的 HTTP 方法处理 URL ,HTTP方法如下(加粗的方法较为常见):

方法 说明
GET 以未加密的形式将数据发送到服务器,最常见的方法
HEAD 和GET方法相同,但没有响应体
POST 用于将HTML表单数据发送到服务器,POST方法接收的数据不由服务器缓存
PUT 用上传的内容替换目标资源的所有当前表示
DELETE 删除由URL给出的目标资源的所有当前表示

默认情况下,Flask路由只回应 GET 请求。可以使用 route() 装饰器的 methods 参数来处理不同的 HTTP 方法。

将以下脚本另存为welcome.html,放在templates文件夹中。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>HTTP方法</title>
</head>
<body><form action = "http://localhost:5000/login" method = "post"><p>Enter Name:</p><p><input type = "text" name = "username" /></p><p><input type = "submit" value = "submit" /></p></form>
</body>
</html>

flask代码如下:

from flask import Flask, redirect, url_for, request, render_template
app = Flask(__name__)@app.route('/')
def index():return render_template('welcome.html')@app.route('/welcome/<name>')
def welcome(name):return f'welcome {name}'@app.route('/login', methods=['POST', 'GET'])
def login():if request.method == 'POST':user = request.form['username']return redirect(url_for('welcome', name=user))else:user = request.args.get('username')  # GET方法获取数据,args是包含表单参数对及其对应值对的列表的字典对象。return redirect(url_for('welcome', name=user))if __name__ == '__main__':app.run(debug=True)

如果请求方式是POST方法,则通过以下代码获得从表单数据获得的“username”参数的值:

user = request.form['username']

如果请求方式是GET方法,则通过以下代码获得从表单数据获得的“username”参数的值:

user = request.args.get('username')

args是包含表单参数对及其对应值对的列表的字典对象,与’username’参数对应的值将传递到/welcome URL中,即

/login?username=Kint

8.文件存放

flask项目中,static文件夹中存放CSS 和 JavaScript文件,templates文件夹中存放html文件。app.py与templates和static文件夹同级目录。

/app.py
/templates/index.html
/static/style.css/jquery.js

果然想要更改路径可以在初始化Flask实例时进行修改

app = Flask(__name__, static_folder='', template_folder='')

9.渲染模板

使用 render_template() 方法可以渲染模板,提供模板名称和需要作为参数传递给模板的变量。

在templates文件夹下创建render_template.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>render_template</title>
</head>
<body><h2>渲染模板</h2>{{ my_int }}<br>{{ my_str }}<br>{{ my_list }}<br>{{ my_dict }}<hr><h2>列表数据获取</h2>{{ my_list[0] }}<br>{{ my_list.1 }}<hr><h2>字典数据获取</h2>{{ my_dict['name'] }}<br>{{ my_dict.age }}<hr><h2>算术运算</h2>{{ my_list.0 + 10 }}<br>{{ my_list[0] + my_list.1 }}
</body>
</html>

flask代码如下:

from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')
def index():int_ = 1024str_ = 'Hello World!'list_ = [1, 2, 3, 4, 5]dict_ = {'name': 'Kint', 'age': 23}# render_template方法:渲染模板# 参数1: 模板名称  参数n: 传到模板里的数据return render_template('render_template.html', my_int=int_, my_str=str_, my_list=list_, my_dict=dict_)if __name__ == '__main__':app.run(debug=True)

效果如下:

Flask 是使用 Jinja2 这个模板引擎来渲染模板,更多内容,详见官方 Jinja2 模板文档。

10.Request对象

部分属性如下(加粗的较为常见):

属性 说明
method 请求方法,比如GET、POST
data 以字符串的形式存储请求的数据
files 上传的文件,类型为MultiDict
args 解析URL中提交的参数,类型为MultiDict
form 上传的表单数据,类型为MultiDict
values 包含args和form的数据,类型为CombineMultiDict
json 解析JSON数据,如果没有则返回None
cookies 包含客户端传输的所有 cookies ,类型为MultiDict
headers 请求头信息,类似字典,可通过关键词获取对应得信息

在templates文件夹下创建Request.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Request</title>
</head>
<body><form action="/login?a=1&b=2" method="post"><p>账号: <input type="text" name="username"></p><p>密码: <input type="password" name="password"></p><input type="submit"></form>
</body>
</html>

flask代码如下:

from flask import Flask, request, render_template
import jsonapp = Flask(__name__)@app.route('/')
def index():return render_template("Request.html")@app.route('/login', methods=["GET", "POST"])
def login():print('request.method:\n', request.method)print('request.data:\n', request.data)print('request.request.args:\n', request.args)print("request.request.args.get('b'):\n", request.args.get('c'))print('request.form:\n', request.form)print("request.request.form.get('password'):\n", request.form.get('password'))print('request.values:\n', request.values)print('request.json:\n', request.json)print('request.cookies:\n', request.cookies)print('request.headers:\n', request.headers)return json.dumps(request.form) # 将MultiDict数据处理为JSON数据if __name__ == '__main__':app.run(debug=True)

效果如下:

后端输出如下:

以request.form为例,在获取MultiDict的值时,推荐使用request.form.get(key)而不直接使用request.form[key],前一种方式可以避免关键词缺失而导致的KeyError。

获取各种路径,本例中的URL为http://127.0.0.1:5000/login?a=1&b=2

print('url: ', request.url)
print('base_url: ', request.base_url)
print('host: ', request.host)
print('host_url: ', request.host_url)
print('path: ', request.path)
print('full_path: ', request.full_path)

输出为:

url:  http://127.0.0.1:5000/login?a=1&b=2
base_url:  http://127.0.0.1:5000/login
host:  127.0.0.1:5000
host_url:  http://127.0.0.1:5000/
path:  /login
full_path:  /login?a=1&b=2

11.Cookie

Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。比如网站为了辨别用户身份、进行会话跟踪需要把一些数据 (例如:登录状态、用户名称) 储存在用户本地终端上,这些数据被称为 Cookie。

Request对象包含Cookie的属性,它是所有Cookie变量及其对应值的字典对象。

在Flask中,对Cookie的处理步骤为:

  1. 使用Response对象的set_cookie()方法设置cookie
  2. 通过request.cookies的方式获取cookies,返回的是一个字典
  3. 使用Response对象的delete_cookie()方法设置cookie

在templates文件夹下创建get_cookie.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>获取cookie</title>
</head>
<body><h2>在服务端获取cookie: <b>{{cookie}}</b></h2>
</body>
</html>

在templates文件夹下创建show_cookie_by_JQuery.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>设置cookie</title><script src="../static/jquery-3.6.0.js" type="text/javascript" charset="utf-8"></script>
</head>
<body><h2>在服务端设置cookie</h2><h2>在客户端通过JQuery读取cookie: <b id='cookie'></b></h2>
</body>
<script>$('#cookie').text(document.cookie);
</script>
</html>

flask代码如下:

from flask import Flask, request, Response, render_template, make_response, redirect, url_forapp = Flask(__name__)@app.route('/')
def index():return redirect(url_for('set_cookie'))  # 重定向响应的URL# 获取cookie
@app.route('/get_cookie')
def get_cookie():cookie = request.cookies.get('user') # 获取关键字为user对应cookie的值print(cookie)return render_template('get_cookie.html', cookie=cookie)# 设置cookie
@app.route('/set_cookie')
def set_cookie():html = render_template('show_cookie_by_JQuery.html')response = make_response(html)  # 设置响应体# response = Response(html)response.set_cookie('user', 'Kint')return response# 删除cookie
@app.route('/del_cookie')
def del_cookie():html = render_template('show_cookie_by_JQuery.html')response = Response(html)response.delete_cookie('user')return responseif __name__ == '__main__':app.run(debug=True)

在set_cookie()函数中,首先渲染模板文件show_cookie_by_JQuery.html,通过make_response()方法设置响应体并返回Response对象,然后设置cookie。以下两种写法作用相同:

response = make_response(html)  # 设置响应体
response = Response(html)

在浏览器中输入http://127.0.0.1:5000/set_cookie,可以看到在响应头信息中已经设置好cookie的数据了。

在浏览器中输入http://127.0.0.1:5000/get_cookie,可以看到请求头信息中cookie的数据,并且将cookie传输到服务端上。

在浏览器中输入http://127.0.0.1:5000/del_cookie,此时响应体信息中已经没有user对应的cookie值了。

12.会话Session

与Cookie不同,Session数据存储在服务器上,用来存储用户的信息 (例如登录状态、用户名称)。Session 有一个唯一标识 ID,对应一个用户,在服务端使用 ID 可以查找到对应用户的数据,故Flask应用程序需要一个定义的密钥SECRET_KEY

以下代码简单实现判断用户是否登录功能:

from flask import Flask, redirect, url_for, request, sessionapp = Flask(__name__)
app.secret_key = 'abc'@app.route('/')
def index():if 'user' in session:# 获取会话中的用户信息user = session.get('user')return '登录用户是:' + user + '<br>' + "<b><a href = '/logout'>点击这里注销</a></b>"return "<h3>暂未登录</h3><br>" + "<a href = '/login'></b>点击这里登录</b></a>"@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':# 设置会话中的用户信息session['user'] = request.form['user']return redirect(url_for('index'))return '''<form action="" method="post"><p><input type="text" name="user"/></p><p><input type="submit" value="登录"/></p></form>'''@app.route('/logout')
def logout():# 删除会话中的用户信息session.pop('user')return redirect(url_for('index'))if __name__ == '__main__':app.run(debug=True)

效果如下:

实例1.上传表单数据

文件结构如下:

/app.py
/templates/login.html/result.html

app.py代码如下:

from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def student():return render_template('login.html')@app.route('/result',methods = ['POST', 'GET'])
def result():if request.method == 'POST':result = request.form #拿到前端传输的表单数据return render_template("result.html",result = result)if __name__ == '__main__':app.run(debug = True)

在templates文件夹下创建login.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>实例1.上传表单数据—登录页面</title>
</head>
<body><form action="http://localhost:5000/result" method="POST"><p>Name <input type = "text" name = "Name" /></p><p>Email <input type = "text" name = "Email" /></p><p><input type = "submit" value = "submit" /></p></form>
</body>
</html>

在templates文件夹下创建result.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>实例1.上传表单数据-结果页面</title>
</head>
<body><table border = 1>{% for key, value in result.items() %}<tr><th> {{ key }} </th><td> {{ value }}</td></tr>{% endfor %}</table>
</body>
</html>

实例2.上传下载文件

文件结构如下:

/app.py
/templates/index.html/upload.html
/upload/download_sample.txt

app.py代码如下:

from flask import Flask, render_template, request, send_from_directory
from werkzeug.utils import secure_filenameimport osapp = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'upload/'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000  # 上传文件大小限制为16M,如果超过会抛出异常@app.route('/')
def upload_file():return render_template('index.html')@app.route('/upload', methods=['GET', 'POST'])
def upload():if request.method == 'POST':f = request.files['file']print(request.files)# secure_filename检查客户端上传的文件名,确保安全,注意文件名称不要全中文!!!f.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))return render_template('upload.html')else:return render_template('index.html')@app.route('/download/<filename>', methods=['GET', 'POST'])
def download(filename):# as_attachment=True 表示文件作为附件下载return send_from_directory('./upload', filename, as_attachment=True)if __name__ == '__main__':app.run(debug=True)

upload函数中,f.save的作用是将文件保存到指定路径中。在使用secure_filename检验上传文件名称时,注意名称尽量为英文!

download函数中,send_from_directory方法将upload目录下的指定文件发送到客户端,as_attachment=True表示文件作为附件下载。

在templates文件夹下创建index.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>实例2.上传下载文件</title>
</head>
<body><h3>上传文件</h3><form action="http://localhost:5000/upload" method="POST" enctype="multipart/form-data"><input type="file" name="file"  /><input type="submit" value="提交" /></form><h3>下载文件</h3><a href="/download/download_sample.txt">download_sample.txt</a>
</body>
</html>

在templates文件夹下创建upload.html文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>实例2.文件上传成功页面</title>
</head>
<body><h3>文件上传成功!</h3>
</body>
</html>

Flask入门学习教程相关推荐

  1. MAYA 2022基础入门学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.41 GB |时长:4.5小时 包含 ...

  2. 3dmax Vray建筑可视化入门学习教程

    面向初学者的3Ds Max Vray最佳Archviz可视化课程 从安装到最终图像的一切都将从头开始教授,不需要任何经验 大小解压后:3.25G 时长4h 6m 1280X720 MP4 语言:英语+ ...

  3. Blender 3.0基础入门学习教程 Introduction to Blender 3.0

    成为Blender通才,通过这个基于项目的循序渐进课程学习所有主题的基础知识. 你会学到什么 教程获取:Blender 3.0基础入门学习教程 Introduction to Blender 3.0- ...

  4. Maya游戏角色绑定入门学习教程 Game Character Rigging for Beginners in Maya

    准备好开始为游戏制作自己的角色动画了吗? 你会学到什么 了解Maya的界面 优化并准备好你的模型,为游戏做准备 了解关节以及如何使用它们来构建健壮的角色骨骼,以便在任何游戏引擎中制作动画 了解IK和F ...

  5. 三维地形制作软件 World Machine 基础入门学习教程

    <World Machine课程>涵盖了你需要的一切,让你有一个坚实的基础来构建自己的高质量的电影或视频游戏地形. 你会学到什么 为渲染或游戏开发创建高分辨率.高细节的地形. 基于Worl ...

  6. Blender3.0动画制作入门学习教程 Learn Animation with Blender (2021)

    要求 下载并安装Blender.免费下载和免费用于任何目的. 描述 加入我的动画课程. 在本课程中,我将从头开始讲述在Blender中创建动画场景的过程. 从第一步到最终渲染.在这个课程中,我们将使用 ...

  7. UE5真实环境设计入门学习教程

    大小解压后:4.69G 时长4h 30m 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 虚幻引擎5–面向初学者的真实环境设计 Unreal Engine 5 – Rea ...

  8. ZBrush全面入门学习教程 Schoolism – Introduction to ZBrush

    ZBrush全面入门学习教程 Schoolism – Introduction to ZBrush ZBrush全面入门学习教程 Schoolism – Introduction to ZBrush ...

  9. Maya基础入门学习教程

    Maya基础入门学习教程 视频:.MKV, 1280x720, 共57节课 时长 4小时25分钟,3GB 语言:英语+中文字幕(根据原英文字幕机译更准确)+原英文字幕 指导老师:Shane Whitt ...

最新文章

  1. php编写一个学生类_PHP实现简单的学生信息管理系统(web版)
  2. 大厂程序员跳槽去小公司当CTO,是一种怎样的体验?
  3. 风险管理、收尾管理和知识产品管理
  4. 云原生,开发者的黄金时代
  5. spark 安装配置
  6. Android模拟器之神奇Genymotion的安装
  7. 机器学习实战(笔记)------------KNN算法
  8. 【Python的黑魔法】实例方法、静态方法和类方法
  9. Nim游戏(初谈博弈)
  10. qt中tinyxml2的基本使用方法
  11. 用 S5PV210 学习 Linux (一) 刷机(一)
  12. Android逆向不可不知的smali语言
  13. 锦天科技被盛大收购 23岁创始人成亿万富翁
  14. c语言求最小公倍数——三种方法
  15. Vue----组件注册
  16. 13.爬虫训练场集成文件采集案例,来学习一下怎么实现的
  17. hive:正则:匹配中文/英文/数字(REGEXP 和 rlike)
  18. CoAP学习笔记——CoAP格式详解
  19. 云开发周公解梦微信小程序源码/支持流量主功能
  20. redis系列--你真的入门了吗?redis4.0入门~

热门文章

  1. 001-photoscan学习笔记
  2. 7家公司拿了5个offer,无非就是问源码、分布式微服务这些
  3. 小米(MI) CXB6-1QM 米家插线板 6位基础版拆解暴力维修
  4. LTE CSG小区概念
  5. 2018全国穿越机竞速联赛沪上3月31日启动
  6. java jackson jobject_在Scalatra中响应JSON格式的诸多问题
  7. 测试:面试问题(多精全)
  8. 【运维面试】帮你找到公司的业务及运维负责内容-面试前必看
  9. Python学习之调换顺序
  10. 蓝魔i100pro刷linux,双系统新旗舰 蓝魔i100 Pro首发评测