zoukankan      html  css  js  c++  java
  • 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)

    app.add_url_rule参数

    from flask import Flask
    app = Flask(__name__)
    app.debug = True
    
    # strict_slashes该参数是用来设置严格模式,当设置为False时/index和/index/都可以被识别
    # redirect_to是路由跳转
    @app.route('/index', strict_slashes=False, redirect_to='/login')
    def index():
        return 'index'
    
    @app.route('/login/<int:nid>')
    def login(nid):
        print(nid)
        return 'login'
    
    
    if __name__ == '__main__':
        app.run()
    @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"]
    #对URL最后的 / 符号是否严格要求
    strict_slashes = None
        '''
            @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>')
        '''
    
    #子域名访问
    subdomain = None, 
        '''
        #C:WindowsSystem32driversetchosts
        127.0.0.1       www.liuqingzheng.com
        127.0.0.1       admin.liuqingzheng.com
        127.0.0.1       buy.liuqingzheng.com
        
        from flask import Flask, views, url_for
        app = Flask(import_name=__name__)
        app.config['SERVER_NAME'] = 'liuqingzheng.com:5000'
        @app.route("/", subdomain="admin")
        def static_index():
            """Flask supports static subdomains
            This is available at static.your-domain.tld"""
            return "static.your-domain.tld"
        #可以传入任意的字符串,如传入的字符串为aa,显示为 aa.liuqingzheng.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()
            
        访问:
        http://www.liuqingzheng.com:5000/dynamic
        http://admin.liuqingzheng.com:5000/dynamic
        http://buy.liuqingzheng.com:5000/dynamic
        '''

    路由系统支持正则

    '''
    当我们需要使用路由匹配正则时
    1.导入from werkzeug.routing import BaseConverter
    2.写一个类继承BaseConverter,初始化实现__init__方法,实现to_python和to_url两个函数
    3.app.url_map.converters['regex'] = RegexConverter添加到flask中
    4.绑定的装饰器@app.route('/index/<regex("d+"):nid>'),书写注册的正则
    5.regex正则匹配出的结果交给to_python,进行一系列自定义操作后return出来
    6.当我们做反向解析的时候,参数传给to_url,return才是我们需要拼接到路由上的
    
    '''
    
    from flask import Flask, views, url_for
    from werkzeug.routing import BaseConverter
    
    app = Flask(__name__)
    
    class RegexConverter(BaseConverter):
        '''
        自定义url匹配正则表达式
        '''
        def __init__(self, map, regex):
            super().__init__(map)
            self.regex = regex
    
        def to_python(self, value):
            '''
            路由匹配时,匹配成功后传递给视图函数中参数的值
            '''
            return int(value)
    
        def to_url(self, value):
            '''
            使用url_for反向生成url时,传递的参数经过该方法处理,返回的值用于生成url中的参数
            '''
            val = super().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=nid))
        return 'index ok'
    
    if __name__ == '__main__':
        app.run()

     89

  • 相关阅读:
    Java学习笔记12---向上转型-父类的对象引用指向子类对象
    Java学习笔记11---静态成员变量、静态代码块、成员变量及构造方法的初始化或调用顺序
    Java学习笔记10---访问权限修饰符如何控制成员变量、成员方法及类的访问范围
    Java学习笔记9---类静态成员变量的存储位置及JVM的内存划分
    Java学习笔记8---类的静态成员变量与静态成员方法的访问与调用方式
    Java学习笔记7---父类构造方法有无参数对子类的影响
    Java学习笔记6---字符串比较方法compareTo(String str)
    地址总线、数据总线、寻址能力、字长及cpu位数等概念之间的关系
    Alpha事后诸葛亮
    第05组 Alpha冲刺(4/4)
  • 原文地址:https://www.cnblogs.com/sxchen/p/11839303.html
Copyright © 2011-2022 走看看