Day89 flask框架之初识

一.什么是flask?

1.和django一样都是基于python开发的web框架

2.和django一样是同步的框架

3.依赖jinja2模板和Werkzeug WSGI服务的一个微型框架

二.安装flask

pip3 install flask

三.werkzeug简介

Werkzeug是一个基于WSGI的工具包,可以作为一个Web框架的底层库,它封装好了很多Web框架的东西,比如Request,Response

四.flask快速使用

from flask import Flask
# 实例化生成一个FLask对象
app = Flask(__name__)

# 将'/'和视图函数index绑定,并添加到路由中
@app.route('/')
def index():
    return 'ok'

if __name__ == '__main__':
    # run()本质是调用了run_simple()
    app.run()

五.flask基本使用之四剑客

flask可以直接返回字符串,也可以返回html页面,也可以重定向到其他页面,也可以返回json数据

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

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

    # 2.返回html页面,可以使用模板语法
    # dic = {'age': 18}
    # return render_template("index.html", name='sxc', dic=dic)

    # 3.重定向页面
    # return redirect('/login')

    # 4.返回json数据
    # info = [{'name': 'sxc'}, {'name': 'zzj'}]
    # return jsonify(info)

@app.route('/login')
def login():
    return 'login'

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

六.flask配置文件的四种方式

# flask的配置文件
from flask import Flask
app = Flask(__name__)

# 第一种配置方式,只能配置两种
# app.debug = True
# app.secret_key = '123'

# 第二种配置,以字典的形式
# app.config['DEBUG'] = True

# 第三种,以文件的形式
# app.config.from_pyfile('settings.py')

# 第四种,以类的方式(推荐)
app.config.from_object('settings.ProductionConfig')


@app.route('/index')
def index():
    print(123)
    return 'ok'

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

具体的配置文件

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.route('/index/<int:nid>', methods=['POST', 'GET'], endpoint='hhh')

通过源码分析得到的新方式

app.add_url_rule('/index/<string:nid>', methods=['GET', 'POST'], view_func=index, endpoint='hhh')

路由系统的本质

def decorator(f):
    endpoint = options.pop("endpoint", None)
    self.add_url_rule(rule, endpoint, f, **options)
    return f
'''
内部代码self.add_url_rule(rule, endpoint, f, **options)
这里的self指代的就是app,rule就是/index, f就是index函数
endpoint是为该路由取的别名,不传默认是函数名
view_func就是f就是index,
endpoint必须有值,当不传的情况下,默认使用函数名,如果不使用装饰器,并且view_func也不传,那么endpoint就会没有值,那么就会报错
'''

路由中的<string:nid>是它的有名分组,前面的是指定类型,后面的是传入的参数

CBV(源码分析)

# CBV的控制类
from flask import Flask, views
app = Flask(__name__)
app.debug = True

class IndexView(views.View):
    def dispatch_request(self):
        print('Index')
        return 'index'

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

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

# 内部源码
@classmethod
    def as_view(cls, name, *class_args, **class_kwargs):
        def view(*args, **kwargs):
            self = view.view_class(*class_args, **class_kwargs)
            return self.dispatch_request(*args, **kwargs)
        view.view_class = cls  # 将控制类赋值给view_class
        view.__name__ = name  # 将name赋值给__name__
        view.__doc__ = cls.__doc__
        view.__module__ = cls.__module__
        view.methods = cls.methods
        view.provide_automatic_options = cls.provide_automatic_options
        return view
'''
上面源码的view.__name__ = name十分重要,
因为endpoint必须有值,当不传的时候默认是函数的__name__,
如果这步不设置,那么所有控制类的endpoint就都是view了,这样会出错
所以必须提前设置view.__name__ = name,故而这个name我们必须传入,
当然我们传入name之后还是可以指定endpoint
'''

CBV的不同请求方式的不同执行函数

# 自定义的CBV代码
class IndexView(views.MethodView):
    # decorators = [,,,]  # 装饰器,可以有多个
    def get(self):
        return 'index get'
    def post(self):
        return 'index post'

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

# 源码,继承MethodView
class MethodView(with_metaclass(MethodViewType, View)):
    def dispatch_request(self, *args, **kwargs):
        meth = getattr(self, request.method.lower(), None)
        # 如果没传默认是get方法
        if meth is None and request.method == "HEAD":
            meth = getattr(self, "get", None)
        assert meth is not None, "Unimplemented method %r" % request.method
        # 传了就是对应的方法,即meth=get/post
        # 下面加括号调用之后就执行自定义函数对应的方法
        return meth(*args, **kwargs)

猜你喜欢

转载自www.cnblogs.com/sxchen/p/11839303.html