Flask框架 请求与响应 & 模板语法
- 2019 年 10 月 8 日
- 筆記
目录
Flask框架 请求与响应 & 模板语法
简单了解Flask框架
Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。 它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。 另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展, 其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站。 #安装Flask - pip3 install Flask - 1.1.1 Flask库文件(安装Flask时自动安装) - Jinja2 模板渲染库 - MarkupSafe 返回安全标签 只要Flask 返回模板或者标签时都会依赖MarkupSafe - Werkzeug 德文“工具” == uWSGI 底层是 WSGI Flask项目启动都是基于Werkzeug

Flask 框架 与 Django 框架对比
Django 框架 - 原生组件非常丰富 教科书式框架 - Django.Model - ORM 面向对象操作数据库 - Django.Form Form组件 - Django.ModelForm ModelForm - Django.Session Model Session - Admin CsrfToken 跨站请求伪造 Django框架(缺点) 加载项巨大 资源浪费 Django框架 适合大型,密集型项目 Flask Web框架 - Flask 非常短小精悍 - 精简到只有一个 Session Flask 第三方组件 非常全 Flask框架(缺点) 第三方组件 - 运行稳定性相对较差 Flask框架 适合小型,API服务类项目
简单使用Flask提供服务
# 三行启动Flask 提供服务 from flask import Flask app = Flask(__name__) app.run() #访问一下看看效果

# 启动Flask 提供服务,访问返回页面,"HelloWorld" from flask import Flask # 导入Flask 类创建Flask应用对象 app = Flask(__name__) # app = application @app.route("/index") # 为 Flask 应用对象增加路由 def index(): # 与路由绑定的视图函数 视图函数名尽可能保持唯一 return "HelloWorld" # “” 相当于 Django 中的 HttpResponse if __name__ == '__main__': # 当前文件处于脚本状态时运行如下代码 app.run() # 启动Flask 应用 #访问一下看看效果

Flask 中的 Response(响应)
return "字符"
@app.route("/index") def index(): return "HelloWorld" # "HelloWorld" 相当于 Django中的HttpResponse返回响应 (效果如上图)
render_template("HTML文件")

#html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>郭楷丰</title> </head> <body> <h1>你好</h1> </body> </html> #python代码 from flask import Flask, render_template app = Flask(__name__) @app.route("/home") def home(): return render_template("home.html") # 模板存放路径 templates if __name__ == '__main__': app.run() #访问一下看看效果

redirect("/home") 重定向
from flask import Flask, render_template, redirect app = Flask(__name__) @app.route("/home") def home(): return render_template("home.html") @app.route("/re") def re(): return redirect("/home") #重定向到home if __name__ == '__main__': app.run() #访问一下看看效果


小结: # 3xx HTTP status # 4xx 错误 客户端 # 5xx 错误 服务器 redirect("/home") 其实就是在ResponseHeaders 中加入了一个 Location:http://127.0.0.1:5000/home
send_file("文件路径") 返回文件
#返回图片示例 代码 #先准备一张图片 1.jpg from flask import Flask,send_file app = Flask(__name__) @app.route("/get_file") def get_file(): return send_file("1.jpg") if __name__ == '__main__': app.run() #访问一下试试看

小结: # 打开并返回文件内容 自动识别文件类型 在ResponseHeaders中加入 # Content-Type:文件类型 - *文件类型 是可以被客户端识别的文件类型(如MP4,MP3,文本,图片等) # 不能识别的类型 下载处理 - 浏览器会下载
jsonify("字符串或数据类型")
from flask import Flask, jsonify app = Flask(__name__) @app.route("/get_json") def get_json(): d = { "name": "gkf" } return jsonify(d) if __name__ == '__main__': app.run() #访问一下试试看

小结: jsonify("字符串或数据类型") 返回标准格式的JSON字符串 # Content-Type:application/json == 标准格式 # Flask 1.1.1 目前版本 支持return d 使用 # return d # 暂时不建议使用 兼容性差 # 直接返回dict时 本质上在执行jsonify(d) jsonify()做了那些事 # 1.打包JSON 序列化JSON字符串 # 2.编写ResponseHeaders 加入 Content-Type:application/json 应用场景: # API 接口 AJAX.post({username:123}){function(data){ obj = data }}
Flask 中的 Request(请求)
request.method(请求类型)
#可以判断客户端的请求来做一些操作 @app.route("/index") def index(): print(request.method) if request.method == 'GET': #如果是get请求,返回一个index.html文件 return render_template("index.html")

request.form (获取form提交数据)
#html代码 <form action="" method="post" enctype="multipart/form-data"> <p>username: <input type="text" name="username"></p> <p><input type="file" name="my_file"></p> <input type="submit" value="登录"> </form> #python代码 def login(): if request.method == 'GET': return render_template('login.html') if request.method == 'POST': print(request.form.get("username")) #直接获取到username对应的值 return redirect("/index")

request.args (获取URL中的数据)
#代码 @app.route("/index") def index(): if request.method == 'GET': print(request.args) #request.args.get('键') 来取值 return render_template("index.html")

request.url (请求地址)
@app.route("/index") def index(): if request.method == 'GET': print(request.url) return render_template("index.html") #当页面输入 http://127.0.0.1:5000/index 打印结果 http://127.0.0.1:5000/index #当页面输入 http://127.0.0.1:5000/index?郭楷丰=318 打印结果 http://127.0.0.1:5000/index?郭楷丰=318
request.url_charset (URL 编码方式)
@app.route("/index") def index(): if request.method == 'GET': print(request.url_charset) return render_template("index.html") #打印结果 utf-8
request.url_root (完整请求地址)
# print(request.url_root) # 请求地址 完整请求地址 host @app.route("/index") def index(): if request.method == 'GET': print(request.url_root) return render_template("index.html") #访问http://127.0.0.1:5000/index 打印结果 http://127.0.0.1:5000/
request.url_rule (请求路由地址)
print(request.url_rule) # 请求路由地址(参数不会获取) #访问http://127.0.0.1:5000/index 打印结果 /index
request.values (接收所有请求中的数据)
#接收所有(GET,POST)请求中的数据,包含了 URL 和 FormData 中的数据 #一般不使用这个 因为url中的参数和form表的的参数它都会获取,如果key值重名,会报错 print(request.values) #访问http://127.0.0.1:5000/index?郭楷丰=318 打印结果 CombinedMultiDict([ImmutableMultiDict([('郭楷丰', '318')]), ImmutableMultiDict([])]) #to_dict 转为字典形式 print(request.values.to_dict()) #访问http://127.0.0.1:5000/index?郭楷丰=318 打印结果 {'郭楷丰': '318'}
request.files (获取页面提交的文件)
@app.route("/login",methods=["GET","POST"]) #重新methods让它只接受"GET","POST"请求 def login(): if request.method == 'GET': return render_template('login.html') if request.method == 'POST': print(request.files) print(request.files.get("my_file")) return redirect("/index") #访问http://127.0.0.1:5000/login 并提交一个文件 执行结果 ImmutableMultiDict([('my_file', <FileStorage: '1_副本.png' ('image/png')>)]) <FileStorage: '1_副本.png' ('image/png')> #获取文件名字
request.files (保存文件示例)
#upload.html文件代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文件上传演示</title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> <p><input type="file" name="my_file"></p> <input type="submit" value="上传图片"> </form> </body> </html> #python代码 import os from flask import Flask, request, render_template app = Flask(__name__) app.secret_key = "!@#$%^&*()" #密钥(对session进行加密) app.debug = True #开启Debug模式 修改代码自动重启项目 @app.route("/upload",methods=["GET","POST"])#重写methods只接收GET与POST请求 def upload(): if request.method == 'GET': return render_template('upload.html') if request.method == 'POST': dir_name = './美女图片' if not os.path.exists(dir_name): os.mkdir(dir_name) my_file = request.files.get("my_file") new_file = os.path.join(dir_name, my_file.filename) my_file.save(new_file) return "上传文件成功" if __name__ == '__main__': app.run()


request (获取其他数据)
# 获取其他数据 # request.headers 请求头中的信息 # request.cookies 请求中cookies的信息 # request.path == request.url_rule 路由地址 # request.host == "127.0.0.1:9527" 获取访问主机地址 # request.host_url == "http://127.0.0.1:9527/" 路由地址 # 特殊提交方式数据获取 # request.json 获取Content-Type:application/json时提交的数据 # Content-Type:application/json # request.data 获取 原始请求体中的数据 b""类型 # Content-Type 无法被识别 或 不包含Form字眼
Flask 模板语言简单使用
#python代码 from flask import Flask, render_template #传给模板的数据 STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'} STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'}, {'name': 'Boy', 'age': 73, 'gender': '男'}, {'name': 'EDU', 'age': 84, 'gender': '女'} ] STUDENT_DICT = { 1: {'name': 'Old', 'age': 38, 'gender': '中'}, 2: {'name': 'Boy', 'age': 73, 'gender': '男'}, 3: {'name': 'EDU', 'age': 84, 'gender': '女'}, } app = Flask(__name__) app.debug = True @app.template_global() def ab(a, b): return a + b @app.route("/stu") def stu(): return render_template("stuinfo.html", stu_info=STUDENT, stu_list=STUDENT_LIST, stu_dict=STUDENT_DICT) if __name__ == '__main__': app.run()
<!--stuinfo.html模板代码--> <!DOCTYPE html> <html lang="zh-CN"> <head> <title>学生信息</title> <style type='text/css'> p{ background-color:#00ffaa; } </style> </head> <body> {{ stu_info }} <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> <table border="1px"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> <tr> <td>{{ stu_info.name }}</td> <td>{{ stu_info.get("age") }}</td> <td>{{ stu_info["gender"] }}</td> </tr> </table> <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> {{ stu_list }} <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> <table border="1px"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> {% for stu in stu_list %} <tr> <td>{{ stu.name }}</td> <td>{{ stu.get("age") }}</td> <td> {% if stu["gender"] != "男" and stu["gender"] != "女" %} 李杰 {% else %} {{ stu["gender"] }} {% endif %} </td> </tr> {% endfor %} </table> <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> {{ stu_dict }} <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> {% for foo in stu_dict %} {{ stu_dict[foo].get("name") }} {{ stu_dict[foo]["age"] }} {{ stu_dict[foo].gender }} {% endfor %} <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> {% for foo,item in stu_dict.items() %} {{ foo }} {{ item.name }} {% endfor %} <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> {{ ab(666,2) }} <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> {% macro my_input(ty,na) %} 请输入用户名 -> <input type="{{ ty }}" name="{{ na }}"> {% endmacro %} <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> <p>这就是我自己创造的input标签:{{ my_input("text","username") }} {{ my_input("password","pass") }} {{ my_input("file","myfile") }}</p> <p>- - - - - - - -✂ - - - - - - - - - - - -分割线- - - - - - - - - - - -✂- - - - - - - -</p> </body> </html>




Flask框架参考手册
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2ky0wzouug4kk
作 者:郭楷丰
出 处:https://www.cnblogs.com/guokaifeng/