配置文件

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参数

 @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:\Windows\System32\drivers\etc  找到HOST,修改配置
            然后吧域名修改成自己的本地服务器127.0.0.1
            加上配置:app.config["SERVER_NAME"] = "haiyan.com:5000"

重定向示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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模式

"""
class IndexView(views.View):
    methods = ['GET']
    decorators = [wapper, ]

    def dispatch_request(self):
        print('Index')
        return 'Index!'

app.add_url_rule('/index', view_func=IndexView.as_view(name='index1'))  # name=endpoint
"""

class IndexView(views.MethodView):
    methods = ['GET']
    decorators = [wapper, ]  # 给所有请求增加装饰器,可以增加多个

    def get(self):
        return 'Index.GET'

    def post(self):
        return 'Index.POST'

app.add_url_rule('/index', view_func=IndexView.as_view(name='index2'))  # name=endpoint


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

Flask中的FBV模式

方式一:
    @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)

请求和响应

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)
"""
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

特殊的装饰器

#!/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、闪现有什么用?

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还可以分类设置

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之前和之后能执行一些我们自己的逻辑

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
posted on 2018-04-25 20:52  Py行僧  阅读(166)  评论(0编辑  收藏  举报