Flask之基础
一,flask
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。
“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。
默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。
二,安装
注意:建议不要直接使用pycharm中提供的flask框架,对于新手来说不太友好
pip install flask
三,与其他web框架比较
1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不管你用得到用不到,反正它全都有,属于全能型框架 2.Tornado 主要特点是原生异步非阻塞,在IO密集型应用和多任务处理上占据绝对性的优势,属于专注型框架 3.Flask 主要特点小而轻,原生组件几乎为0, 三方提供的组件请参考Django 非常全面,属于短小精悍型框架 Django 通常用于大型Web应用由于内置组件足够强大所以使用Django开发可以一气呵成 Tornado 通常用于API后端应用,游戏服务后台,其内部实现的异步非阻塞真是稳得一批 Flask 通常应用于小型应用和快速构建应用,其强大的三方库,足以支撑一个大型的Web应用 Django 优点是大而全,缺点也就暴露出来了,这么多的资源一次性全部加载,肯定会造成一部分的资源浪费 Tornado 优点是异步,缺点是干净,连个Session都不支持 Flask 优点是精悍简单
1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不管你用得到用不到,反正它全都有,属于全能型框架 2.Tornado 主要特点是原生异步非阻塞,在IO密集型应用和多任务处理上占据绝对性的优势,属于专注型框架 3.Flask 主要特点小而轻,原生组件几乎为0, 三方提供的组件请参考Django 非常全面,属于短小精悍型框架 Django 通常用于大型Web应用由于内置组件足够强大所以使用Django开发可以一气呵成 Tornado 通常用于API后端应用,游戏服务后台,其内部实现的异步非阻塞真是稳得一批 Flask 通常应用于小型应用和快速构建应用,其强大的三方库,足以支撑一个大型的Web应用 Django 优点是大而全,缺点也就暴露出来了,这么多的资源一次性全部加载,肯定会造成一部分的资源浪费 Tornado 优点是异步,缺点是干净,连个Session都不支持 Flask 优点是精悍简单
四,flask基本使用
from flask import Flask
app = Flask(__name__) @app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
app.run()
五,flask三剑客
1,response(类比django的HttpResponse)
from flask import Flask
app = Flask(__name__) @app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
app.run()
2,render_template
模板默认在名叫templates文件夹下
from flask import Flask,render_template @app.route("/detail_list")
def detail_list():
return render_template("detail_list.html", students=STUDENT_LIST) # 可以传值到模板中
3,redirect
同django一样,都是在响应头中加 location
from flask import Flask, redirect @app.route("/login", methods=("GET", "POST"))
def login():
msg = ""
if request.method == "POST":
username = request.form.get("username")
pwd = request.form.get("pwd")
if username == "qqq" and pwd == "123":
session["user"] = username
return redirect("/index")
msg = "用户名或者密码错误"
return render_template("login.html", msg=msg)
六,flask中的request
每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的;
flask中基于上下文管理,使用的是一个全局的request对象,每次请求都是本次请求的request;
flaskrequest对象中封装的属性有:
1.request.method
Flask 的 request 中给我们提供了一个 method 属性里面保存的就是前端的请求的方式
print(request.method) # POST 看来可以使用这种方式来验证请求方式了
2.request.form
Form表单中传递过来的值 使用 request.form 中拿到
print(request.form) # ImmutableMultiDict([('user', 'sss'), ('pwd', '123')])
# ImmutableMultiDict 它看起来像是的Dict 就用Dict的方法取值试一下吧
print(request.form["user"]) # sss
print(request.form.get("pwd")) # 123
# 看来全部才对了, ImmutableMultiDict 似乎就是个字典,再来玩一玩它
print(list(request.form.keys())) # ['user', 'pwd'] 看来是又才对了
#如果以上所有的方法你都觉得用的不爽的话
req_dict = dict(request.form)
print(req_dict) # 如果你觉得用字典更爽的话,也可以转成字典操作(这里有坑)
print(request.form.to_dict()) # ImmutableMultiDict([('username', 'qqq'), ('pwd', '123')]) 转化为python的字典格式
3,request.args
request.args 中保存的是url中传递的参数,用法和request.form操作一样
4,request.values
获取所有的数据
5,request.data
content_type不是标准类型的数据,都会丢到data中
request 是基于 mimetype 进行处理的
mimetype的类型 以及 字符串儿 : http://www.w3school.com.cn/media/media_mimeref.asp
如果不属于上述类型的描述,request就会将无法处理的参数转为Json存入到 data 中
其实我们可以将 request.data , json.loads 同样可以拿到里面的参数
如果url和form中的Key重名的话,form中的同名的key中value会被url中的value覆盖
# http://127.0.0.1:5000/req?id=1&user=20
print(request.values.to_dict()) # {'user': 20 'pwd': 'DragonFire', 'id': '1'}
6 .request.files
如果遇到文件上传的话,request.files 里面存的是你上传的文件,但是 Flask 在这个文件的操作中加了一定的封装,让操作变得极为简单
前端代码注意: enctype
后端这样写
print(request.files) # ImmutableMultiDict([('file', <FileStorage: 'DragonFire.txt' ('text/plain')>)])
print(request.files["file"]) # <FileStorage: 'DragonFire.txt' ('text/plain')>
my_file = request.files["file"]
my_file.save("sss.txt") # 保存文件,里面可以写完整路径+文件名
这样我们就成功的保存了一个名叫 "sss.txt" 的文件了,操作还是很简单的
7,其他
print(request.path)# /req
# 当前url路径的上一级路径
print(request.script_root) #
# 当前url的全部路径
print(request.url) # http://127.0.0.1:5000/req
# 当前url的路径的上一级全部路径
print(request.url_root ) # http://127.0.0.1:5000/
# print(request.url) # 请求的url
# print(request.path) # 请求的路径
print(request.headers) # 请求头
print(request.cookies) # cookies
七,flask中的session
flask中的自带的session,特点很明显:它将session存在浏览器的cookies中,以session为键,对真实session经过加密的随机字符串为值存储的;
基本使用:
from flask import Flask,session app = Flask(__name__)
app.secret_key = "类似于加盐,用于加密那个存储在cookie中的 session那个键值对" @app.route("/login", methods=("GET", "POST", ))
def login():
msg = ""
if request.method == "POST":
username = request.form.get("username")
pwd = request.form.get("pwd")
if username == "qqq" and pwd == "123":
session["user"] = username # 设置session
return redirect("/home/")
msg = "用户名或者密码错误!" return render_template("login.html", msg=msg)
这样浏览器cookies 中的 就会存储了键为session,值位加密字符串的键值对了;
cookies 中 session 存储的是通过 secret_key 加密后的 key , 通过这个 key 从flask程序的内存中找到用户对应的session信息
怎么用 session 进行验证呢?
@app.route("/student_list")
def student():
if session.get("user"):
return render_template("student_list.html", student=STUDENT_DICT) return redirect("/login")
八,flask中的路由
1,flask中视图路由的添加
- 使用给视图函数加装饰器的方式:@app.route()
- 使用flask实例对象调用app.add_url_rule()的方式
2. 参数配置
methods : 当前 url 地址,允许访问的请求方式
@app.route("/info", methods=["GET", "POST"])
def student_info():
stu_id = int(request.args["id"])
return f"Hello Old boy {stu_id}" # Python3.6的新特性 f"{变量名}"
endpoint : 反向url地址,默认为视图函数名 (url_for)
from flask import url_for @app.route("/info", methods=["GET", "POST"], endpoint="r_info")
def student_info():
print(url_for("r_info")) # /info
stu_id = int(request.args["id"])
return f"Hello Old boy {stu_id}" # Python3.6的新特性 f"{变量名}"
defaults : 视图函数的参数默认值{"nid":1}
from flask import url_for @app.route("/info", methods=["GET", "POST"], endpoint="r_info", defaults={"nid": 100})
def student_info(nid):
print(url_for("r_info")) # /info
# stu_id = int(request.args["id"])
print(nid) # 100
return f"Hello Old boy {nid}" # Python3.6的新特性 f"{变量名}"
strict_slashes : url地址结尾符"/"的控制 False : 无论结尾 "/" 是否存在均可以访问 , True : 结尾必须不能是 "/"
# 访问地址 : /info
@app.route("/info", strict_slashes=True)
def student_info():
return "Hello Old boy info" # 访问地址 : /infos or /infos/
@app.route("/infos", strict_slashes=False)
def student_infos():
return "Hello Old boy infos"
redirect_to : url地址重定向
# 访问地址 : /info 浏览器跳转至 /infos
@app.route("/info", strict_slashes=True, redirect_to="/infos")
def student_info():
return "Hello" @app.route("/infos", strict_slashes=False)
def student_infos():
return "Hello"
subdomain : 子域名前缀 subdomian="test" 这样写可以得到 test.myserver_name 前提是app.config["SERVER_NAME"] = "myserver_name"
app.config["SERVER_NAME"] = "myserver_name" @app.route("/info",subdomain="test")
def student_info():
return "Hello" # 访问地址为: test.myserver_name /info
3 .动态参数路由
from flask import url_for # 访问地址 : http://127.0.0.1:5000/info/1
@app.route("/info/<int:nid>", methods=["GET", "POST"], endpoint="r_info") # 不指定类型,默认为string
def student_info(nid):
print(url_for("r_info",nid=2)) # /info/2
return f"Hello Old boy {nid}" # Python3.6的新特性 f"{变量名}"
九,flask的配置
1,对已经实例化Flask对象(即app)配置
Flask的配置就是在 app.config 中添加一个键值对,但是你存进去的键必须是config中应该存在的,如果不再存在的话,它会默认无用,就这么放着;
默认的config中的键有:
{
'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,
}
以上这些Key,都可以被改写,当然他们也都是有默认值存在的,如果没有特殊情况,不要改写它的默认值
修改配置的方式大约是两种
1.直接对app.config进行修改
app.config["DEBUG"] = True
2.使用类的方式导入
首先要有一个settings.py的文件
class FlaskSetting:
DEBUG = True
SECRET_KEY = "DragonFire"
然后我们在Flask的启动文件中就可以这么写
from flask import Flask app = Flask(__name__) # type:Flask
app.config.from_object("settings.FlaskSetting") # 这个方法是flask中的配置类Config的一个方法,同样可以把我们配置的键值对,添加到app.congig中
这叫做类导入配置
也可以直接导入一个py文件,app.config.from_pyfile("settings.py"),在文件中直接写如DEBUG=True;
2,在Flask实例化的时候,传递参数进行配置
static_folder = 'static', # 静态文件目录的路径 默认当前项目中的static目录
static_host = None, # 远程静态文件所用的Host地址,默认为空
static_url_path = None, # 静态文件目录的url路径 默认不写是与static_folder同名,远程静态文件时复用
# host_matching是否开启host主机位匹配,是要与static_host一起使用,如果配置了static_host, 则必须赋值为True
# 这里要说明一下,@app.route("/",host="localhost:5000") 就必须要这样写
# host="localhost:5000" 如果主机头不是 localhost:5000 则无法通过当前的路由
host_matching = False, # 如果不是特别需要的话,慎用,否则所有的route 都需要host=""的参数
subdomain_matching = False, # 理论上来说是用来限制SERVER_NAME子域名的,但是目前还没有感觉出来区别在哪里
template_folder = 'templates' # template模板目录, 默认当前项目中的 templates 目录
instance_path = None, # 指向另一个Flask实例的路径
instance_relative_config = False # 是否加载另一个实例的配置
root_path = None # 主模块所在的目录的绝对路径,默认项目目录
我们常用的参数有
static_folder = 'static', # 静态文件目录的路径 默认当前项目中的static目录
static_url_path = None, # 静态文件目录的url路径 默认不写是与static_folder同名,远程静态文件时复用
template_folder = 'templates' # template模板目录, 默认当前项目中的 templates 目录
十,蓝图
1,蓝图基本使用
from flask import Blueprint, render_template add_stu = Blueprint("add_stu", __name__,
static_folder="blue_static",
static_url_path="/static_b",
template_folder="blue_templates") @add_stu.route("/add")
def add():
return render_template("blue_add.html")
一定要把蓝图注册到Flask实例对象中,
app = Flask(__name__, static_url_path="/sss")
app.register_blueprint(add_stu) # 把蓝图注册到Flask实例化对象中
2,蓝图的作用
蓝图插拔机制,使得我们的应用更加灵活,比如某个应用的某些功能我们需要的时候可以使用蓝图的方式注册进去,不需要的时候,直接注释掉注册的那行代码,就可以去掉这个功能了!
3,蓝图的配置和app的配置一模一样
可以有自己的目录结构:
十一, 闪现
没什么暖用的闪现
from flask import Flask, flash, get_flashed_messages @app.route("/home2", endpoint="home2")
@login_required # 注意装饰器的顺序
def home2():
flash("访问了home2页面") # 设置flash,
res = get_flashed_messages() # 获flash中的值,是一个列表,取一次,数据就消失
print(res)
return Markup("<h1>home2页面</h1>")
十二,中间件
也不能叫做中间件,flask中使用2个装饰器,实现类似django中间件的功能
from flask import Flask @app.before_request
def get_session1():
print("get_session1")
if request.path == "/login": # 登陆才能访问
return None
if not session.get("user"):
return redirect("/login") @app.before_request
def get_session2():
print("get_session2") @app.after_request
def process_response1(res):
print("process_response2")
return res @app.after_request
def process_response2(res):
print("process_response1")
return res
执行顺序:和代码的上下有关,正常 before1, before2, after2, after1
十三,sendfile jsonify
1, sendfile
from flask import Flask, request,send_file, jsonify, @app.route("/sf")
def sf():
return send_file("./app.py") # 打开文件并返回
# return send_file("1.jpg") # 可以直接返回图片 和 音频
2, jsonify
from flask import Flask, jsonify @app.route("/jt")
def json_test():
ret_dict = {"name": "ggg"}
return jsonify(ret_dict) # 直接返回json数据,添加content_Type: application/json
Flask之基础的更多相关文章
- 知了课堂 Python Flask零基础 笔记整理
目录 起步 安装Python2.7: Python虚拟环境介绍与安装: pip安装flask: 认识url: URL详解 web服务器和应用服务器以及web应用框架: Flask 第一个flask程序 ...
- 超实用的Flask入门基础教程,新手必备!
Flask入门基础教程 Flask简介 Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活.轻便.安全且容易上手.它可以很好地结合MVC模式进行开发,开发人员分工合 ...
- 2、flask之基础知识点
本篇导航: 路由系统 视图函数 请求与响应 模版语法 session 蓝图(blueprint).闪现 (flash) 扩展 一.路由系统 1.可传入参数: @app.route('/user/< ...
- flask的基础认识
刚开始学习flask基础知识,有了一点点的认识,所以在此大概写一下自己的理解,详细步骤和功能在代码段介绍: from flask import Flask,render_template,reques ...
- flask之基础知识点
本篇导航: 路由系统 视图函数 请求与响应 模版语法 session 蓝图(blueprint).闪现 (flash) 扩展 一.路由系统 1.可传入参数: @app.route('/user/< ...
- 云效(阿里云)流水线 + nginx + uWsgi + flask + python3 基础环境搭建 --备忘
一.开发环境搭建 1.安装python3 yum -y groupinstall "Development tools" yum -y install zlib-devel bzi ...
- Flask的基础二
一.session 除请求对象之外,还有一个 session 对象.它允许你在不同请求间存储特定用户的信息.它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需 ...
- Flask框架基础功能
引言 本文简单汇总Flask框架几大基础功能,包括: 路由系统 模板 数据库 几种常用Flask库 一个简单的Flask事例 Flask是一个基于Python,依赖Jinja2模板和WSGI服务的框架 ...
- Flask框架基础--第一篇
1.flask框架和其他几种框架的优缺点对比 Django : 优点 - 大而全所有组件都是有组织内部开发高度定制化 教科书级别的框架 缺点 - 大到浪费资源,请求的时候需要的资源较高 Flask : ...
- Flask开发基础
Flask是一个使用Python编写的轻量级Web应用框架. 模板引擎使用的Jinja2 Flask框架简单易学,但是其保留了扩展的弹性,可以使用Flask-extension 加入ORM ,窗体验证 ...
随机推荐
- hibernate的load和get有什么作用
① load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常(ObjectNotFoundException)load方法加载实体对象的时候,根据 ...
- win10 mount error 112 : host is down解决方案
摘自:https://www.baidu.com/link?url=xZrOVRqR9gqGRq0esfVaivByR9E5-ixyAuKsQ_8Hiedl1sY6J7ezBlgSW3oe_X-koo ...
- ResponseBody和文件上传
SpringMVC默认使用MappingJacksonHttpMessageConverter对json数据进行转换 <dependency> <groupId>com.fas ...
- [图片问答]打印html样式有问题
1.加载css样式,参考样例10 http://www.c-lodop.com/demolist/PrintSample10.html2.查看lodop内部解析的html信息,见http://www. ...
- mysql查询之分数排名
编写一个 SQL 查询来实现分数排名.如果两个分数相同,则两个分数排名(Rank)相同 +----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 ...
- 「模拟赛20191019」B 容斥原理+DP计数
题目描述 将\(n\times n\)的网格黑白染色,使得不存在任意一行.任意一列.任意一条大对角线的所有格子同色,求方案数对\(998244353\)取模的结果. 输入 一行一个整数\(n\). 输 ...
- 简单的python爬虫教程:批量爬取图片
python编程语言,可以说是新型语言,也是这两年来发展比较快的一种语言,而且不管是少儿还是成年人都可以学习这个新型编程语言,今天南京小码王python培训机构变为大家分享了一个python爬虫教程. ...
- Governing sand(主席树/贪心)(2019牛客暑期多校训练营(第七场))
示例:输入:25 1 11 10 125 1 23 2 3输出:12 题意:n种树,第i种树有P[i]颗,砍掉每颗树的代价是C[i], 高度是H[i].需要用最小的花费砍掉一些树,让最高的树超过一半. ...
- 【LEETCODE】38、167题,Two Sum II - Input array is sorted
package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...
- machine learning相关会议
1. ICML(International Conference on Machine Learning) 链接:https://en.wikipedia.org/wiki/Internation ...