Flask
1、flask初步学习
1.1 创建虚拟环境
mkvirtualenv fl_3 -p python3
1.2 安装
pip install flask
2、案例
2.1 创建一个flask项目
from flask import Flask
app = Flask(__name__)
#__name__指向程序所在的包
#配置路由
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route("/index")
def index():
return "这是我写的路由关系"
if __name__ == '__main__':
app.run(debug=True)
# app.config
- 首先我们导入了 Flask 类。 该类的实例将会成为我们的 WSGI 应用。
- 接着我们创建一个该类的实例。第一个参数是应用模块或者包的名称。如果你使用 一个单一模块(就像本例),那么应当使用 name ,因为名称会根据这个 模块是按应用方式使用还是作为一个模块导入而发生变化(可能是 ‘main’ , 也可能是实际导入的名称)。这个参数是必需的,这样 Flask 才能知道在哪里可以 找到模板和静态文件等东西。更多内容详见 Flask 文档。
- 然后我们使用 route() 装饰器来告诉 Flask 触发函数的 URL 。
- 函数名称被用于生成相关联的 URL 。函数最后返回需要在用户浏览器中显示的信息。
把它保存为 hello.py 或其他类似名称。请不要使用 flask.py 作为应用名称,这会与 Flask 本身发生冲突。
2.2 Flask创建对象的几个参数
"""
def __init__(
self,
import_name, flask程序所在包的名称,决定了访问静态的时候查找路径
static_url_path=None, 静态文件的访问路径,可以不指定
static_folder="static", 静态文件存储的文件夹
static_host=None,
host_matching=False,
subdomain_matching=False,
template_folder="templates", 模板文件夹
instance_path=None,
instance_relative_config=False,
root_path=None,
):
"""
2.3 run的参数
"""
:param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
have the server available externally as well. Defaults to
``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
if present.
:param port: the port of the webserver. Defaults to ``5000`` or the
port defined in the ``SERVER_NAME`` config variable if present.
:param debug: if given, enable or disable debug mode. See
:attr:`debug`.
:param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
files to set environment variables. Will also change the working
directory to the directory containing the first file found.
:param options: the options to be forwarded to the underlying Werkzeug
server. See :func:`werkzeug.serving.run_simple` for more
information.
"""
2.3.1 关于调试模式的修改
app.debug=True
app.run()
# app.run(debug=True)
2.3.2 配置文件的设置
2.3.2.1 关于从类对象中加载
# class Config(object):
# DEBUG=True
#进行app的配置,将配置文件或者配置类加载进app
app.config.from_object(Config)
2.3.2.2 关于从文件中加载
DEBUG=True
app.config.from_pyfile("config.ini")
2.3.2.3 获取配置的参数
print(app.config.get("DEBUG"))
2.4 关于路由的设置
2.4.1 关于源码的解读
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (``GET``, ``POST`` etc.). By default a rule
just listens for ``GET`` (and implicitly ``HEAD``).
Starting with Flask 0.6, ``OPTIONS`` is implicitly
added and handled by the standard request handling.
"""
2.4.2 关于路径配置
@app.route("/userinfo/<int:user_id>",methods=["POST","GET"])
def userinfo(user_id):
# return "获取用户的信息"
return jsonify({"err:msg":"ok"})
注意点:
1、Route中,用于请求方式的配置,用methods这个方法来进行指定,是一个列表
2、用<>来进行参数的指定
3、对于地址传参的问题,可以用类型来约束,如果不写,默认是string字符串
2.4.3 转换器
DEFAULT_CONVERTERS = {
"default": UnicodeConverter,
"string": UnicodeConverter,
"any": AnyConverter,
"path": PathConverter,
"int": IntegerConverter,
"float": FloatConverter,
"uuid": UUIDConverter,
}
string (缺省值) 接受任何不包含斜杠的文本
int 接受正整数
float 接受正浮点数
path 类似 string ,但可以包含斜杠
uuid 接受 UUID 字符串
2.4.4 自定义转换器
2.4.4.1 定义
class MyCoverter(BaseConverter):
def __init__(self,url_map,*args):
super(MyCoverter,self).__init__(url_map)
self.regex=args[0]
app.url_map.converters["myre"]=MyCoverter
@app.route("/userinfo/<myre('\d{5}'):user_id>",methods=["POST","GET"])
def userinfo(user_id):
# return "获取用户的信息"
return jsonify({"err:msg":"ok"})
@app.route("/username/<myre('asd'):user_name>",methods=["POST","GET"])
def username(user_name):
# return "获取用户的信息"
return jsonify({"err:msg":"ok"})
注意点:
1、继承于baseconverter
2、需要额外的参数,用来承接将来需要书写的正则规则
3、要regex进行重新赋值
2.5 请求勾子
2.5.1 before_first_request
#请求钩子
@app.before_first_request
def before_first_request():
print("在第一次请求之前")
功能:
1、在处理第一次请求前执行
2、利用:进行数据库的连接操作
2.5.2 before_request
@setupmethod
def before_request(self, f):
"""Registers a function to run before each request.
For example, this can be used to open a database connection, or to load
the logged in user from the session.
The function will be called without any arguments. If it returns a
non-None value, the value is handled as if it was the return value from
the view, and further request handling is stopped.
"""
self.before_request_funcs.setdefault(None, []).append(f)
return f
@app.before_request
def before_request():
print("在请求之前")
#此时判断用户的请求是否符合规范,如果符合,继续访问,如果不符合,直接return
注意点:
1、在每一次请求调用之前运行
2、在调用的时候不需要传递参数
3、如果它有一个非空的返回值,name返回值会被当做响应,之后请求将不再进入视图进行处理
4、运用
(1)数据库连接
(2)在session中下载用户的相关信息
2.5.3 after_request
@app.after_request
def after_request(response):
print("请求之后")
return response
注意点:
1、在每一次请求调用之后运行
2、在调用的过程中需要传递参数,参数是一个响应对象
3、必须要有返回值,返回值也是一个响应对象,可处理可不处理
2.5.4 teardown_request
@app.teardown_request
def teardown_request(a):
print(a)
print("teardown")
def teardown_request(self, f):
"""Register a function to be run at the end of each request,
regardless of whether there was an exception or not. These functions
are executed when the request context is popped, even if not an
actual request was performed.
Example::
ctx = app.test_request_context()
ctx.push()
...
ctx.pop()
When ``ctx.pop()`` is executed in the above example, the teardown
functions are called just before the request context moves from the
stack of active contexts. This becomes relevant if you are using
such constructs in tests.
Generally teardown functions must take every necessary step to avoid
that they will fail. If they do execute code that might fail they
will have to surround the execution of these code by try/except
statements and log occurring errors.
When a teardown function was called because of an exception it will
be passed an error object.
The return values of teardown functions are ignored.
.. admonition:: Debug Note
In debug mode Flask will not tear down a request on an exception
immediately. Instead it will keep it alive so that the interactive
debugger can still access it. This behavior can be controlled
by the ``PRESERVE_CONTEXT_ON_EXCEPTION`` configuration variable.
"""
self.teardown_request_funcs.setdefault(None, []).append(f)
return f
2.6 报错信息的展示
@app.errorhandler(404)
def hello_world1(e):
print(e)
return '404 my error'
注意点:
1、需要参数,将报错信息展示
2.7 request
@app.route("/index",methods=["GET","POST"])
def index():
# abort(504)
print(request)
print(request.method)
print(request.form)
print(request.args)
print(request.files)
print(request.data)
return "这是我写的路由关系"
注意点:
1、如果是form表单发送过来的post,用request.form
2、如果是图片数据,用的是request.files来获取数据
3、Files获取的数据取对象用的是get方式获取
4、Get获取的对象,直接用save()来进行文件的保存,注意点是要写保存路径
2.8 响应
2.8.1 展示
@app.route("/userinfo/<int:user_id>",methods=["POST","GET"])
def userinfo(user_id):
# return "获取用户的信息"
data={
"name":"ming",
"age":18
}
return jsonify(data)
2.9 状态保持
2.9.1 cookie(存储在客户端)
@app.route("/set_cookie",methods=["GET","POST"])
def set_cookie():
response_obj = make_response("ok")
response_obj.set_cookie("name","123456",max_age=600)
return response_obj
@app.route("/get_cookie",methods=["GET","POST"])
def get_cookie():
print(request.cookies.get("name","654321"))
return "ok"
2.9.2 session(会话,存放在服务端)
@app.route("/set_session",methods=["GET","POST"])
def set_session():
session["hello"]="654321"
return "ok"
"""
session有两种存储方式:1.存在客户端的cookie中
2.存储在服务端,mysql,redis,mongodb
"""
@app.route("/get_session",methods=["GET","POST"])
def get_session():
print(session)
return "ok"
secret_key
SECRET_KEY = "dfhgvkkfgjjugjbjhgjhhbjbvjhv"
注意点:
(1)session是依赖于cookie的
(2)Session在使用的过程中,必须要指定secret_key
2.10 上下文
上下文:相当于容器,保存了一些程序运行的时候需要的信息
"""
上下文:相当于一个容器,保存运行信息
有两种:请求上下文:
1.request:封装了args,data,cookie等信息
2.session:封装了敏感的用户信息
应用上下文:
存储的是应用程序中的变量,通过
current_app获取
"""
2.10.1 请求上下文(request context)
请求上下文:保存的是客户端与服务端交互的数据
请求上下文对象:
Request:封装是HTTP请求的内容
Session:记录了当前会话的信息,就是用来保存用户信息
2.10.2 应用上下文
应用上下文:程序运行的时候,保存的数据信息
current_app
存储变量:
1、加载的配置文件
2、连接了那些数据库
3、运行在那个机器上,IP多少
4、等
@app.route("/app_info",methods=["GET","POST"])
def app_info():
current_app.text = "123456"
return current_app.name
@app.route("/app_info2",methods=["GET","POST"])
def app_info2():
return current_app.text
g
Flask 程序全局的一个临时变量,充当中间人的作用
@app.route("/app_g",methods=["GET","POST"])
def app_g():
g.name = "new"
return g.name
g.name = ‘张三’
3、模板(jinja2)
3.1 jinja2模板
Jinja2模板是由Python实现的模板语言
设计思路:来源于Django的模板引擎
3.2 在flask中返回jinja2模板
@app.route("/index")
def index():
dict1={
“a”:123456,
“b”:654321
}
return render_template(“index.html”,dict1=dict1)