Flask详细介绍及使用实例
Flask攻略
python三大框架预览
Python Web框架分类 功能分类: a:收发消息相关(socket) b:根据不同的URL执行不同的函数(业务逻辑相关的) c:实现动态网页(字符串的替换) Web框架分类: 1、自己实现b,c,使用第三方的a(Django) 2、自己实现b,使用第三方的a,c(Flask) 3、自己实现abc(Tornado) 两个模块 web服务器程序 《---WSGI协议---》 web应用程序 1、wsgiref Django开发环境使用的就是wsgiref模块 2、jinja2(Flask) 渲染HTML页面,其实就是实现字符串的替换
python三大框架优缺点
Flask:
优点: 小而精,短小精悍,第三方组件特别多
缺点: 组件更新速度取决于开源者
Tornado:
优点: 原生的WebSocket, 异步任务, IO非阻塞玩
缺点: 没有组件,Session都没有
Django:
优点: 大而全,组件非常全面
缺点: 太大,重量级框架,加载太大,浪费资源
Flask的优势
Flask中的Werkzuge原理,__call__() Flask的第一个Hello Flask Flask的 HTTPresponse render_template redirect Flask中的 request Flask中的 Jinja2 ,Markup Flask中的 session secret_key Flask中的路由系统 url_for
Flask中Werkzuge原理
from werkzeug.wrappers import Response, Request from werkzeug.serving import run_simple # application源码里面 get_wsgi_headers 里面有个__call__方法 # 可以调用__call__ 在执行flk的时候执行call里面的结果 @Request.application def flk(r): print(r.url) if r.url == '/123': asd() return Response("hello") # flk run_simple("127.0.0.1", 5500, flk) def asd(): print('kermit') asd()
Flask三剑客
# HTTPresponse: return "Hello Flask" # render_template: return render_template("login.html") #templates # redirect: return redirect("/login")
示例:
# Httpresponse @app.route("/index") def index(): return "Hello Flask" # render_template @app.route("/login") def login(): return render_template("login.html") # redirect @app.route("/") def root_path(): return redirect("/login")
Flask需要自己开启:(流程如下)
from flask import Flask, render_template, redirect app = Flask(__name__) app.run() # 可以自定义ip 端口 和debug模式
Flask的request
request.method 获取请求方式 request.form 获取FromData数据(通常情况下的POST请求) request.args 获取GET方式提交的数据 request.files 获取file request.url_about 获取所有的关于URL的参数 request.values 获取全部提交方式 to_dict 坑,覆盖,GET覆盖POST request.headers 获取头部信息 request.cookie 获取客户端cookie request.json 数据头:application/json request.data 在没有任何数据头的情况提交的POST
Flask的模板语言
# Flask 基于 Jinja2 做了一层小的封装,向前端传递数据 render_template 参数传递 stu = {k1:v1} {{ stu }} <td>{{ stu.name }}</td> <td>{{ stu["age"] }}</td> {% if stu.get("gender") == "中" %} <td>男</td> {% else %} <td>{{ stu.get("gender") }}</td> {% endif %} STUDENT_LIST = [ {'name': 'stu1', 'age': 38, 'gender': '中'}, {'name': 'stu2', 'age': 73, 'gender': '男'}, {'name': 'stu3', 'age': 84, 'gender': '女'} ] <td>{{ stu.0.name }}</td> <td>{{ stu[0]["age"] }}</td> {% if stu[0].get("gender") == "中" %} <td>男</td> {% else %} <td>{{ stu.0.get("gender") }}</td> {% endif %} @apl.template_global() def a_b_sum(a,b): return a+b {{ a_b_sum(123,234) }} @apl.template_filter() def a_b_c_sum(a,b,c): return a+b+c {{ 123 | a_b_c_sum(1,2) }}
注意:安全字符串,Markup相当于模板里面有safe
{{ input | safe }} Markup() : Markup("<input type='text' name='input_tag'>")
pycharm识别模板语言的格式:设置jinja2的语言
Session
secret_key = "" 这个是开启session必备的参数
form flask import session app.secret_key = "随意" session["user"] = "xxxx" if session.get("user")
Jsonify
json的转换兼容性比json模块强
from flask import jsonify # import json # Flask的jsonify是等同于json # 区别是json的转换兼容性比json模块强 @flk.route('/json') def get_json(): res = { "user_id": 1, "username": "kermit", "password": "123" } # return json.dumps(res) return jsonify(res)
Flask路由
flk.route() "/index" 路由地址 "/index/<nid>" 动态路由地址(视图函数需要nid参数) "/index/<int:nid>" 动态路由地址 "/files/<filename>" <> 里面的filename可以是本地文件内的任何一个文件全名,可以把任意存在的文件内容打印到页面上
# 可以把所有文件内容显示到页面上面 @flk.route('/files/<filename>') def files(filename): return send_file(filename)
补充
methods=["GET","POST"] 允许URL的请求方式 endpoint="index" 反向URL操作,可以解决Inner重名的问题 redirect_to="/index2" 服务器端页面跳转 301永久性重定向 strict_slashes=False 可以使用"/"结尾 反之不可以 defaults={"nid":1} 视图函数默认参数
Flask配置
settings.FlaskSettings
DEBUG = True app.config["secret_key"] = "xxxxx" TESTING = True { 'DEBUG': False, # 是否开启Debug模式 'TESTING': False, # 是否开启测试模式 'PROPAGATE_EXCEPTIONS': None, # 异常传播(是否在控制台打印LOG) 当Debug或者testing开启后,自动为True 'PRESERVE_CONTEXT_ON_EXCEPTION': None, # 一两句话说不清楚,一般不用它 'SECRET_KEY': None, # 之前遇到过,在启用Session的时候,一定要有它 'PERMANENT_SESSION_LIFETIME': 31, # days , Session的生命周期(天)默认31天 'USE_X_SENDFILE': False, # 是否弃用 x_sendfile 'LOGGER_NAME': None, # 日志记录器的名称 'LOGGER_HANDLER_POLICY': 'always', 'SERVER_NAME': None, # 服务访问域名 'APPLICATION_ROOT': None, # 项目的完整路径 'SESSION_COOKIE_NAME': 'session', # 在cookies中存放session加密字符串的名字 'SESSION_COOKIE_DOMAIN': None, # 在哪个域名下会产生session记录在cookies中 'SESSION_COOKIE_PATH': None, # cookies的路径 'SESSION_COOKIE_HTTPONLY': True, # 控制 cookie 是否应被设置 httponly 的标志, 'SESSION_COOKIE_SECURE': False, # 控制 cookie 是否应被设置安全标志 'SESSION_REFRESH_EACH_REQUEST': True, # 这个标志控制永久会话如何刷新 'MAX_CONTENT_LENGTH': None, # 如果设置为字节数, Flask 会拒绝内容长度大于此值的请求进入,并返回一个 413 状态码 'SEND_FILE_MAX_AGE_DEFAULT': 12, # hours 默认缓存控制的最大期限 'TRAP_BAD_REQUEST_ERRORS': False, # 如果这个值被设置为 True ,Flask不会执行 HTTP 异常的错误处理,而是像对待其它异常一样, # 通过异常栈让它冒泡地抛出。这对于需要找出 HTTP 异常源头的可怕调试情形是有用的。 'TRAP_HTTP_EXCEPTIONS': False, # Werkzeug 处理请求中的特定数据的内部数据结构会抛出同样也是“错误的请求”异常的特殊的 key errors 。 # 同样地,为了保持一致,许多操作可以显式地抛出 BadRequest 异常。 # 因为在调试中,你希望准确地找出异常的原因,这个设置用于在这些情形下调试。 # 如果这个值被设置为 True ,你只会得到常规的回溯。 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', # 生成URL的时候如果没有可用的 URL 模式话将使用这个值 'JSON_AS_ASCII': True, # 默认情况下 Flask 使用 ascii 编码来序列化对象。如果这个值被设置为 False , # Flask不会将其编码为 ASCII,并且按原样输出,返回它的 unicode 字符串。 # 比如 jsonfiy 会自动地采用 utf-8 来编码它然后才进行传输。 'JSON_SORT_KEYS': True, #默认情况下 Flask 按照 JSON 对象的键的顺序来序来序列化它。 # 这样做是为了确保键的顺序不会受到字典的哈希种子的影响,从而返回的值每次都是一致的,不会造成无用的额外 HTTP 缓存。 # 你可以通过修改这个配置的值来覆盖默认的操作。但这是不被推荐的做法因为这个默认的行为可能会给你在性能的代价上带来改善。 'JSONIFY_PRETTYPRINT_REGULAR': True, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, }
蓝图(Blueprint)
from flask import Blueprint,render_template,redirect reg = Blueprint("reg",__name__,template_folder="reg_temp",static_folder="regs",static_url_path="/regs") @reg.route("/reg") def reg_user(): return render_template("reg_index.html") from flask import Flask import reg_user app = Flask(__name__) app.register_blueprint(reg_user.reg) if __name__ == '__main__': app.run("0.0.0.0", 9527, debug=True)
1.Flask实例配置
app.config.form_object("setting.FlaskSetting")
app.DEBUG = True 开启Debug模式,该完代码不用手动重启
app.SECRET_KEY = "xxxxx" 开启session必备参数
2.初始化配置(Flask,Blueprint)
template_folder="reg_temp",
static_folder="regs",
static_url_path="/regs"
3.蓝图Blueprint
在app实例中注册蓝图app.register_blueprint(reg_user.reg)
实例化蓝图对象reg = Blueprint("reg",__name__,template_folder="reg_temp",static_folder="regs",static_url_path="/regs")
蓝图对象同样与Flask对象,具备独立模板和静态目录
from flask import Blueprint, render_template, redirect import DATA student_list = Blueprint('student_list', __name__, static_folder="list_static", static_url_path="/list_static") # 蓝图实例对象一定不能与视图函数同名 @student_list.route('/list') def list(): return render_template('index.html')
4.before_request after_request before_frist_request
before_request 在请求进入视图函数之前做出的处理
after_request 在视图函数返回给用户之前做出的处理
before_frist_request 在第一次请求进入视图函数之前做出的处理
# 类似于Django中间件的功能 @flk.before_request # 在请求之前 def be1(): print('在请求进入App之前做出处理') # 判断url是不是/login if request.path == "/login": print('当前访问的页面url是:', request.path) # True返回None不作任何操作往下走 return None if session.get("user"): print('userSession存在,直接访问页面!') return None else: print('user不存在,跳转到login页面') return redirect("/login") @flk.before_request def be2(): print('执行be2') # 在请求之后 @flk.after_request def af1(response): print('在此时执行了after1') return response @flk.after_request def af2(response): print('在此时执行了after2') return response # 第一次请求前执行 @flk.before_first_request def be_first(): print('第一次请求') # 报错发送的状态码显示的结果 @flk.errorhandler(404) def error_page(arg): return "当前页面不存在!"
5.errorheadler(404)
def error_page(arg)
错误信息头
第一个Flask
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/08/27 17:19 # @Author : MJay_Lee # @File : flask_demo_test.py # @Contact : limengjiejj@hotmail.com from flask import Flask # 导入Flask类 app = Flask(__name__) # 实例化Flask对象 app @app.route("/") # app中的route装饰器 def index(): # 视图函数 return "first flask app" app.run("0.0.0.0",5000,debug=True) # 启动Flask Web 服务
Werkzuge
- android AlarmManager讲解
- Intent和PendingIntent的区别
- android程序崩溃后重启
- jQuery源码——.html()方法原理解析
- 【翻译】JavaScript内存泄露
- 【翻译】ES6生成器简介
- 浅谈事件冒泡
- Github page搭建博客使用自定义插件的方法
- 【翻译】JavaScript中5个值得被广泛使用的数组方法
- 【翻译】浏览器渲染Rendering那些事:repaint、reflow/relayout、restyle
- Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制
- 《JQuery技术内幕》读书笔记——自调用匿名函数剖析
- 【代码+论文】通过ML、Time Series模型学习股价行为
- .NET Core 系列5 :使用 Nuget打包类库
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 来我们再聊聊 KMP 算法 -- 我懂,你也得懂
- 【pytorch】简单的线性回归
- 简单的并查集的实现
- 【python-leetcode269-拓扑排序】火星字典
- 通俗点聊聊算法 - 排序(3)快速排序,亲测
- springmvc之如何对表单数据进行校验
- 基于TypeScript封装Axios笔记(七)
- 2015年javaB组1-4题解析与理解
- 【matplotlib】绘制散点图
- LeetCode刷题心得 -- map的妙用
- 2015javaB组第五题表格计算
- 【线性回归】读取txt
- 走近STL - Vector,再次见面
- 【线性回归】标准方程法
- 133: error: in C++98 XXX must be initialized by constructor, not by '{...}'