• flask基本功能(配置文件,路由,视图函数,请求和响应,模板,session,蓝图,中间件,闪现,常用装饰器)


    配置文件

    flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:
        {
            'DEBUG':                                get_debug_flag(default=False),  是否开启Debug模式
            'TESTING':                              False,                          是否开启测试模式
            'PROPAGATE_EXCEPTIONS':                 None,                          
            'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
            'SECRET_KEY':                           None,
            'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
            'USE_X_SENDFILE':                       False,
            'LOGGER_NAME':                          None,
            'LOGGER_HANDLER_POLICY':               'always',
            'SERVER_NAME':                          None,
            'APPLICATION_ROOT':                     None,
            'SESSION_COOKIE_NAME':                  'session',
            'SESSION_COOKIE_DOMAIN':                None,
            'SESSION_COOKIE_PATH':                  None,
            'SESSION_COOKIE_HTTPONLY':              True,
            'SESSION_COOKIE_SECURE':                False,
            'SESSION_REFRESH_EACH_REQUEST':         True,
            'MAX_CONTENT_LENGTH':                   None,
            'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
            'TRAP_BAD_REQUEST_ERRORS':              False,
            'TRAP_HTTP_EXCEPTIONS':                 False,
            'EXPLAIN_TEMPLATE_LOADING':             False,
            'PREFERRED_URL_SCHEME':                 'http',
            'JSON_AS_ASCII':                        True,
            'JSON_SORT_KEYS':                       True,
            'JSONIFY_PRETTYPRINT_REGULAR':          True,
            'JSONIFY_MIMETYPE':                     'application/json',
            'TEMPLATES_AUTO_RELOAD':                None,
        }
     
    方式一:
        app.config['DEBUG'] = True
     
        PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...)
     
    方式二:
        app.config.from_pyfile("python文件名称")
            如:
                settings.py
                    DEBUG = True
     
                app.config.from_pyfile("settings.py")
     
        app.config.from_envvar("环境变量名称")
            环境变量的值为python文件名称名称,内部调用from_pyfile方法
     
     
        app.config.from_json("json文件名称")
            JSON文件名称,必须是json格式,因为内部会执行json.loads
     
        app.config.from_mapping({'DEBUG':True})
            字典格式
     
        app.config.from_object("python类或类的路径")
     
            app.config.from_object('pro_flask.settings.TestingConfig')
     
            settings.py
     
                class Config(object):
                    DEBUG = False
                    TESTING = False
                    DATABASE_URI = 'sqlite://:memory:'
     
                class ProductionConfig(Config):
                    DATABASE_URI = 'mysql://user@localhost/foo'
     
                class DevelopmentConfig(Config):
                    DEBUG = True
     
                class TestingConfig(Config):
                    TESTING = True
     
            PS: 从sys.path中已经存在路径开始写
         
     
        PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录

    我们常用的方法

    复制代码
    from flask import Flask,render_template,redirect
    app = Flask(__name__)
    
    # 配置文件
    app.config.from_object("settings.DevelopmentConfig")
    
    
    @app.route('/index',methods=['GET','POST'])
    def index():
    
        return ""
    
    if __name__ == '__main__':
        app.run()
    复制代码

    settings

    复制代码
    class BaseConfig(object):
        DEBUG = True
        SECRET_KEY = "asudflkjdfadjfakdf"
    
    
    class ProductionConfig(BaseConfig):
        DEBUG = False
    
    
    class DevelopmentConfig(BaseConfig):
        pass
    
    
    class TestingConfig(BaseConfig):
        pass
    复制代码

    settings中可以定义多种配置,我们根据不同的环境使用不同的配置

    路由

    两种添加路由的方式

    复制代码
    方式一:
      @app.route('/xxxx')  # @decorator
      def index():
         return "Index"
    方式二:
      def index():
         return "Index"
      app.add_url_rule('/xxx', "n1", index)  #n1是别名
    复制代码

    执行@app.route('/xxx')时,首先执行app.route('/xxx'),这个方法的源码如下

    所以decorator=app.route('/index',methods=['GET','POST']),然后再使用@decorator装饰函数,可以看到实际上就是执行了self.add_url_rule(rule, endpoint, f, **options),所以两种添加路由的方式本质是一样的

    添加路由关系的本质:将url和视图函数封装成一个Rule对象)添加到Flask的url_map字段中

    路由中传参

    @app.route('/user/<username>')   #常用的   不加参数的时候默认是字符串形式的
    @app.route('/post/<int:post_id>')  #常用的   #指定int,说明是整型的
    @app.route('/post/<float:post_id>')
    @app.route('/post/<path:path>')
    @app.route('/login', methods=['GET', 'POST'])

    常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:

    复制代码
    DEFAULT_CONVERTERS = {
        'default':          UnicodeConverter,
        'string':           UnicodeConverter,
        'any':              AnyConverter,
        'path':             PathConverter,
        'int':              IntegerConverter,
        'float':            FloatConverter,
        'uuid':             UUIDConverter,
    }
    复制代码

    自定义正则匹配路由

    复制代码
    from flask import Flask, views, url_for
    from werkzeug.routing import BaseConverter
    
    app = Flask(import_name=__name__)
    
    
                class RegexConverter(BaseConverter):
                    """
                    自定义URL匹配正则表达式
                    """
                    def __init__(self, map, regex):
                        super(RegexConverter, self).__init__(map)
                        self.regex = regex
    
                    def to_python(self, value):
                        """
                        路由匹配时,匹配成功后传递给视图函数中参数的值
                        :param value: 
                        :return: 
                        """
                        return int(value)
    
                    def to_url(self, value):
                        """
                        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
                        :param value: 
                        :return: 
                        """
                        val = super(RegexConverter, self).to_url(value)
                        return val
    
                # 添加到flask中
                app.url_map.converters['regex'] = RegexConverter
    
    
                @app.route('/index/<regex("d+"):nid>')
                def index(nid):
                    print(url_for('index', nid='888'))
                    return 'Index'
    
    
                if __name__ == '__main__':
                    app.run()
    复制代码

    反向生成URL: url_for

    endpoint("name")   #别名,相当于django中的name,如果没有定义endpoint,默认为视图函数的函数名

    反向解析需要导入:

    from flask import Flask, url_for

    示例

    复制代码
    from flask import Flask,render_template,redirect,url_for
    app = Flask(__name__)
    
    @app.route('/index',methods=['GET','POST'],endpoint='n1')
    def index():
        v1 = url_for('n1')
        v2 = url_for('login')  # 没有定义endpoint默认为视图函数名
        v3 = url_for('logout')
        print(v1,v2,v3)
        return "Index"
    
    @app.route('/login',methods=['GET','POST'])
    def login():
        return "login"
    
    @app.route('/logout',methods=['GET','POST'])
    def logout():
        return "logout"
    
    if __name__ == '__main__':
        app.run()
    复制代码

    @app.route和app.add_url_rule参数

     View Code

    @app.route和app.add_url_rule参数:
    rule, URL规则
    view_func, 视图函数名称
    defaults=None, 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
    endpoint=None, 名称,用于反向生成URL,即: url_for('名称')
    methods=None, 允许的请求方式,如:["GET","POST"]

    strict_slashes=None, 对URL最后的 / 符号是否严格要求,
    如:
    @app.route('/index',strict_slashes=False),
    访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
    @app.route('/index',strict_slashes=True)
    仅访问 http://www.xx.com/index
    redirect_to=None, 重定向到指定地址
    如:
    @app.route('/index/<int:nid>', redirect_to='/home/<nid>')

    def func(adapter, nid):
    return "/home/888"
    @app.route('/index/<int:nid>', redirect_to=func)

    subdomain=None, 子域名访问
    from flask import Flask, views, url_for

    app = Flask(import_name=__name__)
    app.config['SERVER_NAME'] = 'haiyan.com:5000'


    @app.route("/", subdomain="admin")
    def static_index():
    """Flask supports static subdomains
    This is available at static.your-domain.tld"""
    return "admin.xxx.com"

                                #动态生成
    @app.route("/dynamic", subdomain="<username>")
    def username_index(username):
    """Dynamic subdomains are also supported
    Try going to user1.your-domain.tld/dynamic"""
    return username + ".your-domain.tld"


    if __name__ == '__main__':
    app.run()
    所有的域名都得与IP做一个域名解析:
            如果你想通过域名去访问,有两种解决方式:
              方式一:
                1、租一个域名 haiyan.lalala
                2、租一个公网IP 49.8.5.62
                3、域名解析:
    haiyan.com 49.8.5.62
                4、吧代码放在49.8.5.62这个服务器上,程序运行起来
                  用户可以通过IP进行访问
              方式二:如果是自己测试用的就可以用这种方式。先在自己本地的文件中找
                 C:WindowsSystem32driversetc 找到HOST,修改配置
                然后吧域名修改成自己的本地服务器127.0.0.1
                加上配置:app.config["SERVER_NAME"] = "haiyan.com:5000"

    重定向示例

    复制代码
    from flask import Flask,render_template,redirect
    app = Flask(__name__)
     
    @app.route('/index',methods=['GET','POST'],redirect_to='/new')
    def index():
        return "老功能"
     
    @app.route('/new',methods=['GET','POST'])
    def new():
        return '新功能'
     
     
    if __name__ == '__main__':
        app.run()
    复制代码

    当用户访问/index时会自动重定向到/new

    给多个视图添加装饰器

    复制代码
    from flask import Flask,render_template,redirect
    app = Flask(__name__)
    import functools
    
    def wapper(func):
        @functools.wraps(func)
        def inner(*args,**kwargs):
            print('before')
            return func(*args,**kwargs)
        return inner
    
    
    
    @app.route('/xxxx',methods=['GET','POST'])
    @wapper
    def index():
        return "Index"
    
    
    @app.route('/order',methods=['GET','POST'])
    @wapper
    def order():
        return "order"
    
    if __name__ == '__main__':
        app.run()
    复制代码

    首先要注意的是,装饰器要添加在路由下面,还有就是给多个视图添加同一个装饰器时,由于装饰器装饰后就相当于在执行inner函数,如果视图没有定义endpoint那么都会默认使用函数名,也就是inner,这时多个函数都是inner,会报错,所以要使用

    @functools.wraps(func)来保留原函数的函数名等信息

    视图函数

    Flask中的CBV模式

    复制代码
    方式一:
        @app.route('/index',endpoint='xx')
        def index(nid):
            url_for('xx',nid=123)
            return "Index"
    
    方式二:
        def index(nid):
            url_for('xx',nid=123)
            return "Index"
    
        app.add_url_rule('/index',index)
    复制代码

    请求和响应

     View Code

    from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response

    app = Flask(__name__)


    @app.route('/login.html', methods=['GET', "POST"])
    def login():

    # 请求相关信息
    # request.method
    # request.args
    # request.form
    # request.values
    # request.cookies
    # request.headers
    # request.path
    # request.full_path
    # request.script_root
    # request.url
    # request.base_url
    # request.url_root
    # request.host_url
    # request.host
    # request.files
    # obj = request.files['the_file_name']
    # obj.save('/var/www/uploads/' + secure_filename(f.filename))

    # 响应相关信息
    # return "字符串"
    # return render_template('html模板路径',**{})
    # return redirect('/index.html')

    # response = make_response(render_template('index.html'))
    # response是flask.wrappers.Response类型
    # response.delete_cookie('key')
    # response.set_cookie('key', 'value')
    # response.headers['X-Something'] = 'A value'
    # return response


    return "内容"

    if __name__ == '__main__':
    app.run()

    复制代码
    from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
    from urllib.parse import urlencode,quote,unquote
    app = Flask(__name__)
    
    @app.route('/index',endpoint='xx')
    def index():
        from werkzeug.datastructures import ImmutableMultiDict
      =================
        # get_data = request.args
        # get_dict = get_data.to_dict()
        # get_dict['xx'] = '18'
        # url = urlencode(get_dict)
        # print(url)
      ====================
        # print(request.query_string)
        # print(request.args)
      ==========================
        # val = "%E6%8A%8A%E5%87%A0%E4%B8%AA"
        # print(unquote(val))   #吧上面这样的数据转换成中文
        #
        # return "Index"
    
        # return "Index"
        # return redirect()
        # return render_template()
        # return jsonify(name='alex',age='18')  #相当于JsonResponse
      =======================
        response = make_response('xxxxx')   ##如果是返回更多的值,cookie,headers,或者其他的就可用它
        response.headers['xxx'] = '123123'
        return response
    
    
    if __name__ == '__main__':
        # app.__call__
        app.run()
    复制代码

    返回json格式数据

    from flask import Flask,render_template,redirect,request,jsonify,make_response
    
    return json.dumps({}) # return jsonify({})

    模板

    Flask使用的是Jinja2模板,所以其语法和Django基本无差别

    自定义方法

    复制代码
    from flask import Flask,render_template,redirect,request,jsonify,make_response,Markup
    app = Flask(__name__)
    
    def gen_input(value):
        # return "<input value='%s'/>" %value
        return Markup("<input value='%s'/>" %value)
    
    @app.route('/x1',methods=['GET','POST'])
    def index():
        context = {
            'k1':123,
            'k2': [11,22,33],
            'k3':{'name':'oldboy','age':84},
            'k4': lambda x: x+1,
            'k5': gen_input, # 当前模板才能调用的函数
        }
    
        return render_template('index.html',**context)
    复制代码

    当函数返回的是字符串时,为了防止xss攻击,加了验证,所以页面上显示字符串的形式,解决办法,有两种方式

    在后端Markup

    v5 = Markup("<input type='text' />")

    在前端

    {{ v4|safe }}

    将这些参数传给前端后,前端页面可以采用类似与django的方式渲染

        <h1>{{k1}}</h1>
        <h1>{{k2.0}}  {{k2[0]}} </h1>
        <h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name',888)}}</h1>
        <h1>{{k4(66)}}</h1>
        <h1>{{k5(99)}}</h1>

    这里可以看出flask的渲染方式更贴近python,很多python的语法可以使用,执行函数时也不像django,可以自己加括号执行,还可以传参数

    写一个函数在所有的页面都使用

    template_global和template_filter

    复制代码
    @app.template_global()
    def sb(a1, a2):
        return a1 + a2
    
    
    @app.template_filter()
    def db(a1, a2, a3):
        return a1 + a2 + a3
    复制代码

    这么定义后在前端所有的页面都能调用这两个函数

    调用方式:{{sb(1,2)}} {{ 1|db(2,3)}}

    filter方法的第一个参数就是|的值

    模板继承:和django的一样,extends

    先定义一个母板

    复制代码
    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <div >头部</div>
        <div>
            {% block content %} {% endblock %}
        </div>
        <div >底部</div>
    </body>
    </html>
    复制代码

    然后继承它

    复制代码
    {% extends 'layout.html'%}
    
    {% block content %}
        <h1>{{k1}}</h1>
        <h1>{{k2.0}}  {{k2[0]}} </h1>
        <h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name',888)}}</h1>
        <h1>{{k4(66)}}</h1>
        <h1>{{k5(99)}}</h1>
    {% endblock%}
    复制代码

    session

    除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。

    • 设置:session['username'] = 'xxx'

    • 删除:session.pop('username', None)
     View Code

    """
    1. 请求刚刚达到
    ctx = RequestContext(...)
    - request
    - session=None
    ctx.push()
    ctx.session = SecureCookieSessionInterface.open_session

    2. 视图函数

    3. 请求结束
    SecureCookieSessionInterface.save_session()
    """
    from flask import Flask,session
    app = Flask(__name__)
    app.secret_key = 'sadfasdfasdf'

    @app.route('/x1')
    def index():
    # 去ctx中获取session
    session['k1'] = 123
    session['k2'] = 123
    del session['k2']
    return "Index"


    @app.route('/x2')
    def order():
    print(session['k1'])
    return "Order"

    if __name__ == '__main__':
    app.run()

    # 1. 请求一旦到来
    # app.__call__
    # app.wsgi_app
    # app.open_session

    session的操作和字典相同,默认情况下session存在COOKIE中

    源码简单剖析,之前我们已经知道在执行app.run时实际上执行的就是run_simple方法,也就是app(),这时会调用Flask类中的__call__方法

    这个方法实际上在执行app.wsgi_app

    在wsgi_app方法中首先定义了一个ctx,我们看看self.request_context干了什么

    可以看到这个方法实际上就是返回了RequestContext类的对象,而ctx就是这个类的对象,那么这个类中都定义了些什么呢

    这里首先定义了request,然后也定义了session,所以这个ctx对象包含了request和session,定义request时,又用到了app中的request_class

    这其实是一个类,所以request就是这个类的对象

    定义玩ctx后又执行了ctx.push方法

    在这个方法中定义了self.session,我们来看看self.app.open_session干了什么

    这里实际上执行了self.session_interface.open_session,而session_interface又是一个新的类的对象

    这里其实执行的是SecureCookieSessionInterface()的open_session方法

     

    可以看到在这个方法中首先从cookies中获取session,如果是第一次访问,取不到val,则直接返回self.session_class(),如果有值,则将值反序列化,再返回self.session_class(data),我们再看看self.session_class做了什么

    我们发现这又是一个类,所以上面返回的是这个类的对象

    这个类继承了CallbackDict,而CallbackDict又继承了dict

    所以我们知道了self.session_class返回的对象其实是一个特殊的字典,所以我们能像使用字典一样使用session

     执行完ctx.push后接着要执行

    这个方法其实会去执行我们的视图函数,然后返回

    返回时执行了self.finalize_request

    这个方法中又执行了self.process_response,在这个方法中又执行了一步save_session的操作

    其实是在执行

    而session_interface = SecureCookieSessionInterface(),所以我们又要找到SecureCookieSessionInterface中的save_session方法

    它实际上就是将数据序列化后写入了cookie

    所以session的整体流程就是先从cookie中读取,然后返回一个特殊的字典对象,我们可以修改,最后执行完视图函数后,我们又将修改后的session序列化,然后写入cookie

    特殊的装饰器

     View Code

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from flask import Flask, Request, render_template

    app = Flask(__name__, template_folder='templates')
    app.debug = True


    @app.before_first_request # 只有第一次请求来时执行,后面的都不执行
    def before_first_request1():
    print('before_first_request1')


    @app.before_first_request
    def before_first_request2():
    print('before_first_request2')


    @app.before_request # 类似与django中间件中的process_request
    def before_request1():
    Request.nnn = 123
    print('before_request1')


    @app.before_request
    def before_request2():
    print('before_request2')


    @app.after_request
    def after_request1(response):
    print('before_request1', response)
    return response


    @app.after_request # 类似与django中间件中的process_response
    def after_request2(response):
    print('before_request2', response)
    return response


    @app.errorhandler(404) # 当报404错误时返回的内容
    def page_not_found(error):
    return 'This page does not exist', 404


    @app.template_global() # 定义全局的函数,每个页面都能使用
    def sb(a1, a2):
    return a1 + a2


    @app.template_filter() # 定义过滤函数
    def db(a1, a2, a3):
    return a1 + a2 + a3


    @app.route('/')
    def hello_world():
    return render_template('hello.html')


    if __name__ == '__main__':
    app.run()

    before_request和after_request

    before_request是请求在执行视图函数之前会执行的,after_request是请求执行完视图函数会执行的

    before_request如果返回None则会继续向后执行,当有多个时会按顺序执行,如果有返回值,那么后面的将不会执行,视图函数也不会执行,而是会按倒序执行after_request(这里和django的中间件有些不同)

    有多个before_request时会按顺序执行

    有多个after_request时会按倒序执行

    闪现

    session存在在服务端的一个字典里面,session保存起来,取一次里面还是有的,直到你删除之后才没有了

    1、本质:flash是基于session创建的,flash支持往里边放值,只要你取一下就没有了,相当于pop了一下。不仅把值取走,而且把session里的东西去掉

    2、闪现有什么用?

     View Code

    from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
    app = Flask(__name__)
    app.secret_key ='sdfsdfsdf'

    @app.route('/users')
    def users():
    # 方式一
    # msg = request.args.get('msg','')
    # 方式二
    # msg = session.get('msg')
    # if msg:
    # del session['msg']
    # 方式三
    v = get_flashed_messages()
    print(v)
    return render_template('users.html',msg=v)

    @app.route('/useradd')
    def user_add():
    # 在数据库中添加一条数据
    # 假设添加成功,在跳转到列表页面时,显示添加成功
    # 方式一
    # return redirect('/users?msg=添加成功')
    # 方式二
    # session['msg'] = '添加成功'
    # 方式三
    flash('添加成功')
    return redirect('/users')


    if __name__ == '__main__':
    app.run(debug=True)

    flash中的值被取一次就会删除,不会保留

    flash还可以分类设置

     View Code

    from flask import Flask, session, flash, get_flashed_messages

    app = Flask(__name__)
    app.secret_key = 'asdfasdfasdf'


    @app.route('/x1', methods=['GET', 'POST'])
    def login():
    flash('我要上向龙1', category='x1')
    flash('我要上向龙2', category='x2')
    return "视图函数x1"


    @app.route('/x2', methods=['GET', 'POST'])
    def index():
    data = get_flashed_messages(category_filter=['x1'])
    print(data)
    return "视图函数x2"


    if __name__ == '__main__':
    app.run()

    中间件

    通过上面的分析我们知道当请求过来时会先执行app.run-->run.simple-->app()-->__call__-->app.wsgi_app

    如果我们自己定义了wsgi_app方法,那么就不会执行原来的,而会执行我们自己定义的了,利用这一点我们可以自己定义一个,让请求来了在执行app.wsgi_app之前和之后能执行一些我们自己的逻辑

     View Code

    from flask import Flask
    app = Flask(__name__)
    app.secret_key = 'asdfasdfasdf'

    @app.route('/x2',methods=['GET','POST'])
    def index():
    return "x2"


    class Middleware(object):
    def __init__(self,old_wsgi_app):
    """
    服务端启动时,自动执行
    :param old_wsgi_app:
    """
    self.old_wsgi_app =old_wsgi_app

    def __call__(self, environ, start_response):
    """
    每次有用户请求道来时
    :param args:
    :param kwargs:
    :return:
    """
    print('before')
    obj = self.old_wsgi_app(environ, start_response)
    print('after')
    return obj

    if __name__ == '__main__':
    app.wsgi_app = Middleware(app.wsgi_app)
    app.run()
    """
    1.执行app.__call__
    2.在调用app.wsgi_app方法
    """

    这里要注意在执行app.wsgi_app之前我们无法使用request和session,只能使用最原始的数据

    蓝图

    在之前我们使用flask时所有的内容都是写在一个python文件中的,如果项目规模大了的话,这样做显然是不行的,所以我们需要创建一些项目的目录

    目录结构类似django,manage.py是启动文件,内容如下

    from s8pro import app
    
    if __name__ == '__main__':
        app.run()

    在导入s8pro时会执行该目录下的__init__文件,这个文件的内容

    复制代码
    from flask import Flask
    from .views import account
    from .views import admin
    from .views import user
    
    
    app = Flask(__name__)
    
    
    app.register_blueprint(account.ac)
    app.register_blueprint(admin.ad)
    app.register_blueprint(user.us)
    复制代码

    这里我们实例化了一个app对象,然后将它和其它的蓝图关联

    accout.py

    复制代码
    from flask import Blueprint,render_template
    import redis
    
    ac = Blueprint('ac',__name__)
    
    @ac.route('/login')
    def login():
        conn = redis.Redis()
        return render_template('login.html')
    
    
    @ac.route('/logout')
    def logout():
        return '123'
    复制代码

    admin.py

    复制代码
    from flask import Blueprint
    
    ad = Blueprint('ad',__name__,url_prefix='/admin')
    
    @ad.before_request
    def bf():
        print('before_request')
    
    
    @ad.route('/home')
    def home():
        return 'home'
    
    @ad.route('/xxxx')
    def xxxx():
        return 'xxxx'
    复制代码

    user.py

    复制代码
    from flask import Blueprint
    
    
    us = Blueprint('us',__name__)
    
    @us.route('/info')
    def info():
        return 'info'
    复制代码

    在每个视图文件中我们都可以示例化一个蓝图对象,它的使用和app一样,最后只要把app和蓝图对象关联就可以访问到了

    蓝图还可以定义访问url的前缀,类似于django中的include

    ad = Blueprint('ad',__name__,url_prefix='/admin')

    这样访问时url必须是/admin/***

    蓝图中还可以定义before_request等方法,访问时只有访问到该蓝图中的内容时才会执行该方法,不是全局的

    蓝图用于为应用提供目录划分:

    小型应用程序:示例

    大型应用程序:示例

    其他:

    • 蓝图URL前缀:xxx = Blueprint('account', __name__,url_prefix='/xxx')
    • 蓝图子域名:xxx = Blueprint('account', __name__,subdomain='admin')
      # 前提需要给配置SERVER_NAME: app.config['SERVER_NAME'] = 'xxx.com:5000'
      # 访问时:admin.xxx.com:5000/login.html
  • 相关阅读:
    二分与三分
    NOIP应试技巧
    数论
    并差集
    最短路
    图的遍历

    最小生成树
    树状数组
    线段树
  • 原文地址:https://www.cnblogs.com/xyhh/p/10860389.html
Copyright © 2020-2023  润新知