前言
关于这部分知识点
主要参考了网上各大博客以及知乎等进行总结
链接如下:
Flask官网文档
W3Cschool的python flask
Flask — 框架快速入门
所谓Flask是一个用Python编写的Web应用程序框架
如何安装Flask以及其环境,此处就省略,主要讲解其函数使用等
最简单的一个应用函数就是:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run()
主要的运行本地程序通过app.run()
这个函数也有其内部的参数选择
主要的参数选择为:app.run(host, port, debug, options)
参数可选择为:
参数 | 描述 |
---|---|
host | 要监控的主机名。默认为本机地址,如设置为0.0.0.0则为全网广播 |
port | 默认值为5000,可设置自个的端口号 |
debug | 默认为false,如果想调试,则设置为true |
options | 转发到底层的一个Werkzeug服务器 |
1. 基本概念
1.1 路由
通过装饰器的app.route(rule, options)
主要的参数规则为:
- rule为url绑定
- options为转发给rule对象的参数列表
关于上面的路由函数
还有一种形式可以将其跟url进行绑定
主要通过如下这种形式:
(通过application对象的add_url_rule()函数)
def hello_world():
return 'hello world'
app.add_url_rule('/', 'hello', hello_world)
变量规则
对应的路由函数中,通过向规则参数添加变量部分,动态构建url,变量的标记为<name>
from flask import Flask
app = Flask(__name__)
@app.route('/hello/<name>')
def hello_name(name):
return 'Hello %s!' % name
@app.route('/blog/<int:ID>')
def id(ID):
return 'Blog Number %d' % ID
@app.route('/blog/<float:money>')
def money(money):
return 'Blog Number %f' % money
if __name__ == '__main__':
app.run(debug = True)
具体的访问方式通过http://localhost:5000/hello/码农研究僧
其默认的传参形式为:
参数 | 描述 |
---|---|
int | 整数 |
float | 浮点数 |
path | 目录分割符的斜杆 |
动态构建url的形式
之所以加入这种形式,如果路径改变,则发出去的url会访问不到,修改起来会很麻烦
主要通过url_for()函数
改造上面的代码模块,具体如下:
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/manongyanjiuseng')
def hello_manongyanjiuseng():
return 'Hello manongyanjiuseng'
@app.route('/guest/<guest>')
def hello_guest(guest):
return 'Hello %s' % guest
@app.route('/user/<name>')
def hello_user(name):
if name =='manongyanjiuseng':
return redirect(url_for('hello_manongyanjiuseng'))
else:
return redirect(url_for('hello_guest', guest = name))
if __name__ == '__main__':
app.run(debug = True)
配合HTTP的方法
在路由中还可通过添加methods的方法选择post
将其静态页面放置在html文件中才可被搜索到
html静态文件如下:(login.html)
<html>
<body>
<form action = "http://localhost:5000/login" method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
在逻辑代码模块中的参数如下:
from flask import Flask, redirect, url_for, request
app = Flask(__name__)
@app.route('/success/<name>')
def success(name):
return 'welcome %s' % name
# login的登录页面
@app.route('/login',methods = ['POST', 'GET'])
def login():
# 通过post请求获取到表单,具体获取表单的方式 可以通过request.method这个函数
if request.method == 'POST':
# user用户名通过request.form表单的格式
user = request.form['nm']
return redirect(url_for('success',name = user))
else:
# 如果页面的html请求方式为get,则方法获取,即为request.args.get
user = request.args.get('nm')
return redirect(url_for('success',name = user))
if __name__ == '__main__':
app.run(debug = True)
1.2 模板
一般Flask的模板主要通过jinja2来渲染
将其模板放置在templates文件夹中,跟上面的代码模块逻辑思路差不多
创建一个html文件(hello.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>码农研究僧</title>
</head>
<body>
这是码农研究僧的首页
</body>
</html>
通过视图函数对其模板进行渲染
使用的函数与上面有所区别,注意区分开,render_template
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('hello.html')
通过模板相对应的和视图函数交互
具体的方式如下:
模板中的静态页面通过{{ }}
进行获取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>码农研究僧</title>
</head>
<body>
码农研究僧
<br />{{ my_str }}
<br />{{ my_int }}
<br />{{ my_array }}
<br />{{ my_dict }}
</body>
</html>
其视图函数如下:
(主要传入的参数有字符串、列表、字典等到模板)
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
# 往模板中传入的数据
my_str = '码农研究僧'
my_int = 18
# 列表
my_array = [3, 4, 2, 1, 7, 9]
# 字典
my_dict = {
'name': '码农研究僧',
'age': 18
}
return render_template('hello.html',
my_str=my_str,
my_int=my_int,
my_array=my_array,
my_dict=my_dict
)
引入css或js文件
这部分文件通过static进行引入
主要的demo代码如下:
视图函数还是照旧
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
if __name__ == '__main__':
app.run(debug = True)
区分点在于html代码模块中调用了js文件定义的函数
<html>
<head>
<script type = "text/javascript"
src = "{{ url_for('static', filename = 'hello.js') }}" ></script>
</head>
<body>
<input type = "button" onclick = "sayHello()" value = "Say Hello" />
</body>
</html>
js文件主要是定义了一个函数模块:
function sayHello() {
alert("Hello World")
}
1.3 表单数据、Cookies和Session
在讲解这两个之前,先科普下Request对象
其Request对象的主要参数有如下:
参数 | 描述 |
---|---|
Form | 字典对象,表单的参数以及键值对 |
args | 解析url(问号占位符)后的内容 |
Cookies | 保存名称和对象 |
files | 上传文件的相关数据 |
method | 当前请求的方法 |
Cookie是存储在客户端的,Session是存储在服务端的
关于这部分的知识如果不太熟悉可看我之前的讲解:
【计算机网络】常见面试题集锦(全)
表单数据
视图函数示意代码如下:
from flask import Flask, render_template, request
app = Flask(__name__)
# 默认首页是通过转发student.html的页面表单信息
@app.route('/')
def student():
return render_template('student.html')
# 通过student.html的表单数据 提交之后会触发 result的一个页面请求
# 如果确定是post请求,则会触发表单的数据到result中
# result函数通过字典对象中的表单数据(通过request.form函数),将其发送给result.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)
具体student的表单界面信息如下:
<form action="http://localhost:5000/result" method="POST">
<p>Name <input type = "text" name = "Name" /></p>
<p>Physics <input type = "text" name = "Physics" /></p>
<p>Chemistry <input type = "text" name = "chemistry" /></p>
<p>Maths <input type ="text" name = "Mathematics" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
表单提交之后的验证信息具体如下:
(一键获取的表单的数据)
<!doctype html>
<table border = 1>
{% for key, value in result.items() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }}</td>
</tr>
{% endfor %}
</table>
Cookie
Request对象本身包含了Cookie的属性,包含了cookie的变量及其对应值的字典对象。
通常设置Cookie的属性类似增删改查
- 设置Cookie属性
resp = make_response("success") # 设置响应体
resp.set_cookie("manongyanjiuseng", "manongyanjiuseng", max_age=3600) # 主要通过max_age的属性设置有效期
- 获取Cookie
cookie_1 = request.cookies.get("manongyanjiuseng")
- 删除Cookie
resp = make_response("del success") # 设置响应体
resp.delete_cookie("manongyanjiuseng")
具体完整的示例demo如下:
from flask import Flask, make_response, request # 注意需导入 make_response
app = Flask(__name__)
@app.route("/set_cookies")
def set_cookie():
resp = make_response("success")
resp.set_cookie("manongyanjiuseng", "manongyanjiuseng", max_age=3600) # 主要通过max_age的属性设置有效期
return resp
@app.route("/get_cookies")
def get_cookie():
cookie_1 = request.cookies.get("manongyanjiuseng")
return cookie_1
@app.route("/delete_cookies")
def delete_cookie():
resp = make_response("del success")
resp.delete_cookie("manongyanjiuseng")
return resp
if __name__ == '__main__':
app.run(debug=True)
Session
Session对象是一个字典对象,需要定义一个SECRET_KEY
- 设置session会话变量:
Session['username'] = 'manongyanjiuseng'
- 释放session会话变量:
session.pop('username', None)
完整的demo如下:
from flask import render_template
from flask import make_response
from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
app.secret_key = 'fkdjsafjdkfdlkjfadskjfadskljdsfklj'
@app.route('/')
# 主页面这里每次都会判断以下是否有无session
def index():
if 'username' in session:
username = session['username']
return '登录用户名是:' + username + '<br>' + \
"<b><a href = '/logout'>点击这里注销</a></b>"
return "您暂未登录, <br><a href = '/login'></b>" + \
"点击这里登录</b></a>"
# 登录通知
@app.route('/login', methods = ['GET', 'POST'])
def login():
# 如果获取的结果为post,则获取表单的数据,传递给session,之后跳转到主页面
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form action = "" method = "post">
<p><input type="text" name="username"/></p>
<p><input type="submit" value ="登录"/></p>
</form>
'''
# 退出登录通知
@app.route('/logout')
def logout():
# remove the username from the session if it is there
session.pop('username', None)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug = True)
1.4 重定向和消息闪现
关于重定向主要是使用redirect函数,上面的demo也有使用到
其redirect的函数原型为:Flask.redirect(location, statuscode, response)
主要的代码参数如下:
参数 | 描述 |
---|---|
location | 重定向的url |
statuscode | 发送到浏览器标头,默认为302 |
response | 实例化相应请求 |
具体的代码如下:
from flask import Flask, redirect, url_for, render_template, request, abort
app = Flask(__name__)
@app.route('/')
def index():
return render_template('log_in.html')
@app.route('/login',methods = ['POST', 'GET'])
def login():
if request.method == 'POST':
if request.form['username'] == 'admin' :
return redirect(url_for('success'))
else:
# abort函数是会展示错误代码模块的意思
abort(401)
else:
return redirect(url_for('index'))
@app.route('/success')
def success():
return 'success'
if __name__ == '__main__':
app.run(debug = True)
消息闪现
所谓消息闪现是向用户反馈信息,
使用的函数主要是:flash(message, category)
其参数如下:
参数 | 描述 |
---|---|
message | 闪现的实际消息 |
category | 可选参数,有error、info、warning |
1.5 文件上传
Flask处理文件的时候,配合html的表单即可,将其enctype设置为multipart/form-data
关于文件上传主要通过app.config的配置参数
- 定义文件上传的路径:
app.config['UPLOAD_FOLDER']
- 指定上传文件的最大大小(字节单位):
app.config['MAX_CONTENT_LENGTH']
获取文件的保存位置一般有两种形式
一种是通过request.files[file]
对象的 filename
属性
另一种是secure_filename(f.filename)
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
# 定义文件上传的位置
app.config['UPLOAD_FOLDER'] = 'manongyanjiuseng/'
@app.route('/upload')
def upload_file():
return render_template('upload.html')
@app.route('/uploader',methods=['GET','POST'])
def uploader():
if request.method == 'POST':
f = request.files['file']
print(request.files)
f.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))
return 'file uploaded successfully'
else:
return render_template('upload.html')
if __name__ == '__main__':
app.run(debug=True)
定义的html文件主要如下:(放置在templates模块下)
设置上传的属性,主要通过enctype="multipart/form-data"
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="http://localhost:5000/uploader" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="提交" />
</form>
</body>
</html>
2. 插件扩展
2.1 邮件
邮件的扩展主要通过Flask-Mail
通过pip install Flask-Mail
进行安装
具体设置Flask-Mail的参数有如下:
参数 | 描述 |
---|---|
MAIL_SERVER | 服务器名称或者ip地址 |
MAIL_PORT | 服务器端口号 |
MAIL_USE_TLS | 安全曾的加密是否开启 |
MAIL_USE_SSL | 安全套接字层加密是否开启 |
MAIL_DEBUG | 调试是否开启 |
MAIL_USERNAME | 用户 |
MAIL_PASSWORD | 密码 |
MAIL_DEFAULT_SENDER | 默认用户发件 |
MAIL_MAX_EMAILS | 发送的最大邮件数 |
MAIL_SUPPRESS_SEND | 若app.testing设置为true,则发送被抑制 |
MAIL_ASCII_ATTACHMENTS | 为true,则文件名转换为ASCII |
其类的构造函数:flask-mail.Mail(app = None)
类的方法有:
- send函数发送Message对象的内容
- connect函数与主机链接
- send_message函数发送消息对象
关于Message类的构造函数:
flask-mail.Message(subject, recipients, body, html, sender, cc, bcc,
reply-to, date, charset, extra_headers, mail_options, rcpt_options)
其方法有如下:
-
attach函数:为邮件添加附件
具体参数如下:
filename:附加文件的名字
content_type:MIME类型文件
data:原始数据 -
add_recipient函数:向邮件添加另一个收件人
完整代码如下:
# 引入对应的包名
from flask import Flask
from flask_mail import Mail, Message
app =Flask(__name__)
# 通过Mail函数发送,先创建其实例
mail=Mail(app)
# 设置对应的属性
app.config['MAIL_SERVER']='manongyanjiuseng.com'
app.config['MAIL_PORT'] = 9999
app.config['MAIL_USERNAME'] = 'https://blog.csdn.net/weixin_47872288?spm=1010.2135.3001.5343'
app.config['MAIL_PASSWORD'] = 'manongyanjiuseng'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app)
# 发送mesage函数
@app.route("/")
def index():
msg = Message('Hello', sender = 'https://blog.csdn.net/weixin_47872288?spm=1010.2135.3001.5343', recipients = ['https://blog.csdn.net/weixin_47872288?spm=1010.2135.3001.5343'])
msg.body = "欢迎查看我的博客"
# 发送其邮件信息
mail.send(msg)
return "Sent"
if __name__ == '__main__':
app.run(debug = True)
部署
可以配合使用wsgi容器
关于wsgi的配置可看我这篇文章:
uwsgi启动django以及uwsgi.ini的配置参数详解