说明:
flask是一个轻量级的web框架,被称为微型框架。只提供了一个高效稳定的核心,其它全部通过扩展来实现。意思就是你可以根据项目需要进行量身定制,也意味着你需要不断学习相关的扩展库。

核心:

WSGI系统、调试、路由

模板引擎(Jinja2,是flask核心开发者人员发开的)

安装:

>: pip install flask

 

werkzeug简介

Flask的socket是基于Werkzeug 实现的

Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

 

flask的使用

Flask运行的本质:

from flask import Flask
# 实例化产生一个Flask对象
app = Flask(__name__)
# 装饰器路由
@app.route('/')
def index():
    return 'ok'

if __name__ == '__main__':
    # 本质是 run_simple(host, port, app, **options)
    # app() 调用的是Flask的__call__里的wsgi_app方法,返回response
    app.run()

 

启动参数
参数 说明
debug 是否开启调试模式,默认为False;开启后会有出错调试信息,文件会自动加载。
threaded 是否开启多线程,默认为Flase。
host 指定主机,默认为’127.0.0.1’,设置为’0.0.0.0’后可以通过IP进制访问
port 指定端口,默认为5000。
启动示例:app.run(debug=True, threaded=True, host=‘0.0.0.0’, port=5555)

响应四剑客 render_template,redirect,jsonify

  • 返回字符串

@app.route('/')
def index():
    # 1 直接返回字符串
    return 'ok'
  • 返回HTML 

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def index():
    # 2 返回HTML
    return render_template('index.html')  # 参数: xxx.HTML
  • 跳转页面(重定向)

from flask import Flask, redirect
app = Flask(__name__)

@app.route('/')
def index():
    # 3 跳转页面
    return redirect('/login')  # 参数: url

@app.route('/login')
def login():
    return render_template('login.html')  
  • 返回json数据

from flask import Flask, jsonify
app = Flask(__name__)

@app.route('/')
def index():
    # 4 返回json数据
    dic = {'name':'xionger', 'age': 20}
    return jsonify(dic)  # 参数: 要序列化的数据

 

templates(模板层)

1. 创建templates文件夹
2. 文件夹内创建HTML文件
  • 视图函数向HTML页面传递数据

# 方式一
@app.route('/') def index(): dic = {'name': 'xionger', 'age': 20} return render_template('index.html', num=100, dic_data=dic)
# 方式二
from flask import Flask, render_template, Markup
app = Flask(__name__)

def func(t1, t2):
    return Markup(f'<h1>hahaha{t1}{t2}</h1>')

@app.route('/list',methods=['GET'])
def list():
    return render_template('list.html',html="<h1>hahaha</h1>", func=func)

# list.html
    {{ html|safe }}
    {{ func(1, 2) }}

 

  • 模板语法

<body>
    <p>{{ num }}</p>  100
    <p>{{ dic_data.name }}</p>  xionger
    <p>{{ dic_data.get('name') }}</p>  xionger
    <p>{{ dic_data['name'] }}</p>  xionger
</body>
<!-- 字典, 列表等数据类型在python中如何使用, 在模板中就如何使用 -->

 

<!-- 遍历循环 -->
<body>
    <h1>用户列表</h1>
    <table>
        {% for k,v in user_dict.items() %}
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v['name']}}</td>
            <td>{{v.get('name')}}</td>
            <td><a href="/detail/{{k}}">查看详细</a></td>
        </tr>
        {% endfor %}
    </table>
</body>

 

<!-- 逻辑判断 -->
<body>
    <h1>用户列表</h1>
    <table>
        {% if name %}
          <h1>Hello {{ name }}!</h1>
        {% else %}
          <h1>Hello World!</h1>
        {% endif %}
    </table>
</body>

 

配置文件

  • 方式一

# 这中方式只能配置两种
app.debug=True
app.secret_key="123123"
  • 方式二 :使用config字典

app.config['DEBUG']=True
  • 方式三: 导入文件(插拔式)

settings.py
# DEBUG = True

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
视图函数文件.py
app.config.from_object('settings.DevelopmentConfig')

补充:

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,
    }

 

路由系统

@setupmethod
    def add_url_rule(
        self,
        rule,  # --> 装饰器里的路由
        endpoint=None,  # --> 路由别名
        view_func=None,  # --> 视图函数
        provide_automatic_options=None,
        **options  # 用来接收methods等参数的字典
    ):
        
        if endpoint is None:  # 若路由没有起别名
            # endpoint = 视图函数的名字
            endpoint = _endpoint_from_view_func(view_func)
        # 将endpoint添加到options里
        options["endpoint"] = endpoint
        # 获取methods的值
        methods = options.pop("methods", None)

        # if the methods are not given and the view_func object knows its
        # methods we can use that instead.  If neither exists, we go with
        # a tuple of only ``GET`` as default.
        if methods is None:  
            # methods为空 则默认是GET请求
            methods = getattr(view_func, "methods", None) or ("GET",)
        if isinstance(methods, string_types):
            raise TypeError(
                "Allowed methods have to be iterables of strings, "
                'for example: @app.route(..., methods=["POST"])'
            )
        methods = set(item.upper() for item in methods)

        # Methods that should always be added
        required_methods = set(getattr(view_func, "required_methods", ()))

        # starting with Flask 0.8 the view_func object can disable and
        # force-enable the automatic options handling.
        if provide_automatic_options is None:
            provide_automatic_options = getattr(
                view_func, "provide_automatic_options", None
            )

        if provide_automatic_options is None:
            if "OPTIONS" not in methods:
                provide_automatic_options = True
                required_methods.add("OPTIONS")
            else:
                provide_automatic_options = False

        # Add the required methods now.
        methods |= required_methods

        rule = self.url_rule_class(rule, methods=methods, **options)
        rule.provide_automatic_options = provide_automatic_options

        self.url_map.add(rule)
        if view_func is not None:
            old_func = self.view_functions.get(endpoint)  # endpoint 是视图函数的名字
            if old_func is not None and old_func != view_func:
                raise AssertionError(
                    "View function mapping is overwriting an "
                    "existing endpoint function: %s" % endpoint
                )
            # 若view_functions中有endpoint 则取出赋值给view_func
            # view_func要么必须有值, 要么endpoint有别名, 最终endpoint的值也会赋值给view_func
            self.view_functions[endpoint] = view_func  
            # 如果endpoint有别名 view_func = endpoint
            # 如果endpoint没有有别名 view_func = endpoint(视图函数名字)
路由系统源码

相关文章:

  • 2022-02-10
  • 2022-12-23
  • 2021-11-21
  • 2021-06-13
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-12-30
  • 2022-02-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案