• 第十二篇 Flask 基础篇


    Flask

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。

    “微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。

    默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。

     1 pip install flask 

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

    一 .基本使用

    from flask import Flask
    app = Flask(__name__)
     
    @app.route('/')
    def hello_world():
        return 'Hello World!'
     
    if __name__ == '__main__':
        app.run()

    二 .配置文件

    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 "index"
    
    if __name__ == '__main__':
        app.run()

     setting.py(项目根目录下)

    class BaseConfig(object):
        DEBUG = True
        SECRET_KEY = "asudflkjdfadjfakdf"
    
    
    class ProductionConfig(BaseConfig):
        DEBUG = False
    
    
    class DevelopmentConfig(BaseConfig):
        pass
    
    
    class TestingConfig(BaseConfig):
        pass
    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__)
    
    """
    1. 执行decorator=app.route('/index',methods=['GET','POST'])
    2falsk基础知识与示例. @decorator
         - decorator(index)
    """
    # 路由方式一(*):
    @app.route('/index',methods=['GET','POST'])
    def index():
        return "Index"
    
    # 路由方式二:
    def order():
        return 'Order'
    
    app.add_url_rule('/order',view_func=order)
    
    
    if __name__ == '__main__':
        app.run()
    生成路由2种方式
    from flask import Flask,render_template,redirect,url_for
    app = Flask(__name__)
    
    
    # endpoint 起别名,用于反向生成url
    @app.route('/index',methods=['GET','POST'],endpoint='n1')
    def index():
        v1 = url_for('n1')
        v2 = url_for('login')
        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()
    endpoint(别名)
    from flask import Flask,render_template,redirect,url_for
    app = Flask(__name__)
    
    @app.route('/index/<int:nid>',methods=['GET','POST'])
    def index(nid):
        print(nid,type(nid))
        return "Index2"
    
    if __name__ == '__main__':
        app.run()
    路由匹配
    from flask import Flask,render_template,redirect,url_for
    from werkzeug.routing import BaseConverter
    app = Flask(__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
    
    app.url_map.converters['xxx'] = RegexConverter
    
    @app.route('/index/<xxx("d+"):nid>',methods=['GET','POST'])
    def index(nid):
        print(nid,type(nid))
        v = url_for('index',nid=999) # /index/999
        print(v)
        return "Index"
    
    if __name__ == '__main__':
        app.run()
    自定义url正则匹配路由
    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()
    重定向
    from flask import Flask,render_template,redirect
    
    from gevent import pywsgi
    app = Flask(__name__)
    app.config['SERVER_NAME'] = 'hw.com:5000'
    
    
    @app.route("/dynamic", subdomain="<username>")
    def xxxxxxx(username):
        # 域名为:'www.oldboy.com:5000'
        print(username) # 获取子域名  输出:www
        return 'xxxxx'
    
    @app.route('/index')
    def x():
        print('x')
        return 'xxx'
    
    if __name__ == '__main__':
    
        app.run('127.0.0.1',5000)
    获取子域名
    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()
    装饰器(functool使用)

    四 .视图(cbv-fbv)

    from flask import Flask,render_template,redirect,views
    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"
    
    """
    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()

    五 .请求与相应

    from flask import Flask,render_template,redirect,request,jsonify,make_response
    app = Flask(__name__)
    
    @app.route('/index',methods=['GET','POST'])
    def index():
        # 请求相关
        # request.method
        # request.args
        # request.form
        # request.cookies
        # request.headers
        # request.path
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/' + secure_filename(obj.filename))
    
        # request.values
        # request.full_path
        # request.script_root
        # request.url
        # request.base_url
        # request.url_root
        # request.host_url
        # request.host
    
    
    
        # 响应相关
        return ""
        return json.dumps({}) # return jsonify({})
        return render_template('index.html',n1=123)
        return redirect('/index')
    
    
        # response = make_response(render_template('index.html'))
        # response = make_response("xxxx")
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # response.delete_cookie('key')
        # return response
    
    
    
    
    if __name__ == '__main__':
        app.run()

    六 .模板

    from flask import Flask,render_template,redirect,request,jsonify,make_response,Markup
    app = Flask(__name__)
    
    @app.template_global()
    def sbbbbbbb(a1, a2):
        """
        每个模板中可以调用的函数
        :param a1:
        :param a2:
        :return:
        """
        return a1 + a2
    
    
    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)
    
    
    @app.route('/x2',methods=['GET','POST'])
    def order():
        context = {
            'k1':123,
            'k2': [11,22,33],
        }
    
        return render_template('order.html',**context)
    
    
    
    
    if __name__ == '__main__':
        app.run()
    <!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>
    layout.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>
        <h1>{{sbbbbbbb(1,2)}}</h1>
    {% endblock%}
    index.html
    <!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>
        <h1>{{sbbbbbbb(1,2)}}</h1>
    </body>
    </html>
    order.html

    七 .session

    """
    1. 请求刚刚达到
        ctx = RequestContext(...)
              - request
              - session=None
        ctx.push()
            ctx.session = SecureCookieSessionInterface.open_session
    
    2falsk基础知识与示例. 视图函数
    
    3flsak源码分析上下文管理. 请求结束
        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

    八 .特殊装饰器

    from flask import Flask,render_template,redirect
    app = Flask(__name__)
    
    """
    before_reuqest = [xxxxxxxxxx1,xxxxxxxxxx2]
    """
    @app.before_request
    def xxxxxxxxxx1():
        print('前1')
    
    @app.before_request
    def xxxxxxxxxx2():
        print('前2')
    """
    after_request = [oooooooo1,oooooooo2]
    [oooooooo2,oooooooo1,] reversed(after_request)
    """
    @app.after_request
    def oooooooo1(response):
        print('后1')
        return response
    
    @app.after_request
    def oooooooo2(response):
        print('后2')
        return response
    
    
    
    @app.route('/x1',methods=['GET','POST'])
    def x1():
        print('视图函数x1')
        return "视图函数x1"
    
    @app.route('/x2',methods=['GET','POST'])
    def x2():
        print('视图函数x2')
        return "视图函数x2"
    
    if __name__ == '__main__':
        app.__call__
        app.run()
    from flask import Flask,render_template,redirect
    app = Flask(__name__)
    
    @app.before_request
    def xxxxxxxxxx1():
        print('前1')
        return "不要再来烦我了"
    
    @app.before_request
    def xxxxxxxxxx2():
        print('前2')
    
    @app.after_request
    def oooooooo1(response):
        print('后1')
        return response
    
    @app.after_request
    def oooooooo2(response):
        print('后2')
        return response
    
    
    
    @app.route('/x1',methods=['GET','POST'])
    def x1():
        print('视图函数x1')
        return "视图函数x1"
    
    @app.route('/x2',methods=['GET','POST'])
    def x2():
        print('视图函数x2')
        return "视图函数x2"
    
    if __name__ == '__main__':
        app.__call__
        app.run()
    s2.py
    from flask import Flask,render_template,redirect,request,session
    app = Flask(__name__)
    app.secret_key = 'asdfasdfasdf'
    @app.before_request
    def check_login():
        if request.path == '/login':
            return None
        user = session.get('user_info')
        if not user:
            return redirect('/login')
    
    @app.route('/login',methods=['GET','POST'])
    def login():
        return "视图函数x1"
    
    @app.route('/index',methods=['GET','POST'])
    def index():
        print('视图函数x2')
        return "视图函数x2"
    
    if __name__ == '__main__':
        app.run()
    实践-登录验证

    九 .闪现

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

    十.中间件

    from flask import Flask
    app = Flask(__name__)
    app.secret_key = 'asdfasdfasdf'
    Debug =True
    
    @app.before_request
    def xxxxxxxxxx1():
        print('前1')
    @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')
            from flask import session,request
            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__
        2falsk基础知识与示例.在调用app.wsgi_app方法
        """
    View Code
    from types import MethodType,FunctionType
    
    class Foo(object):
        def fetch(self):
            pass
    
    print(isinstance(Foo.fetch,MethodType))
    print(isinstance(Foo.fetch,FunctionType)) # True
    
    obj = Foo()
    print(isinstance(obj.fetch,MethodType)) # True
    print(isinstance(obj.fetch,FunctionType))
    函数与方法判断

    十一 .蓝图

    蓝图示例
    s8pro/s8pro
        _init_.py
            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)
    
        .views
            -account.py
            -admin.py
            -user.py
    mamage.py
        from s8pro import app
        if __name__ == '__main__':
            app.run()

    附件:项目模板示例

    1小型项目示例 (点击下载)(提取码:huaw)

    1大型项目示例 (点击下载)

    作者:华王 博客:https://www.cnblogs.com/huahuawang/
  • 相关阅读:
    Vector Dictionary HashMap
    崩溃java (打印当前类的地址)
    colspan、rowspan的使用
    基础操作
    安装vuex-devtools插件
    在使用Vuex插件进行状态管理的步骤
    运行cnpm run dev出现错误解决办法
    在使用vue开发时,文件路径的引用(给文件起别名)
    下载脚手架vue.cli出现的问题
    什么是闭包?
  • 原文地址:https://www.cnblogs.com/huahuawang/p/14807641.html
Copyright © 2020-2023  润新知