Flask(2)

本文详细介绍了Flask框架的使用,包括创建虚拟环境和安装,创建Flask项目,路由设置及转换器,请求钩子如before_first_request、before_request、after_request和teardown_request的功能与应用场景,错误处理,以及请求和响应的处理。同时,讨论了模板引擎Jinja2的使用方法,强调了session和cookie的区别,并提醒在使用session时设置secret_key的重要性。
摘要由CSDN通过智能技术生成

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
  1. 首先我们导入了 Flask 类。 该类的实例将会成为我们的 WSGI 应用。
  2. 接着我们创建一个该类的实例。第一个参数是应用模块或者包的名称。如果你使用 一个单一模块(就像本例),那么应当使用 name ,因为名称会根据这个 模块是按应用方式使用还是作为一个模块导入而发生变化(可能是 ‘main’ , 也可能是实际导入的名称)。这个参数是必需的,这样 Flask 才能知道在哪里可以 找到模板和静态文件等东西。更多内容详见 Flask 文档。
  3. 然后我们使用 route() 装饰器来告诉 Flask 触发函数的 URL 。
  4. 函数名称被用于生成相关联的 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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值