• flask 配置文件 路由 视图 模板 中间件


    今日概要

    • wsgi
    • 创建flask对象
      • 模板
      • 静态文件
    • 路由系统
      • 路由的应用:装饰器(推荐)、方法
      • 动态路由
    • 视图
      • FBV
      • CBV
    • 模板
      • 继承
      • include
      • 自定义标签
    • 特殊装饰器
      • before_request充当中间件角色

    wsgi 找源码的流程

    不依赖与flask

    from werkzeug.serving import run_simple
    from werkzeug.wrappers import BaseResponse
    
    def func(environ, start_response):
        print('请求来了')
        response = BaseResponse('你好')
        return response(environ, start_response)
    
    
    if __name__ == '__main__':
        run_simple('127.0.0.1', 5000, func)
    
    """
        1.程序启动,等待用户请求到来
            app.run()
        2.用户请求到来 app()    
            app.__call__
    """
    
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/index')
    def index():
        return 'hello world'
    
    if __name__ == '__main__':
        app.run()
    

    flask对象静态文件的处理

    静态文件的处理。

    1584004941153

    view

    from flask import Flask,render_template
    
    app = Flask(__name__,template_folder='templates',static_folder='static',static_url_path='/xx')
    
    @app.route('/index')
    def index():
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run()
        
    #static_folder参数代表静态文件夹名字
    #static_folder参数 相当与别名 用这个别名就可以找到文件夹
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>首页</h1>
    <!--    <img src="/xx/mm.jpg" />-->
    
        <!-- 建议 -->
        <img src="{{ url_for('static',filename='mm.jpg')}}" />
    </body>
    </html>
    
    #static会自动帮你找 不管你是什么 xx还是什么
    

    配置文件

    创建一个config文件夹 里面有 配置文件全局setting.py与局部localsettings.py配置文件

    py文件导入

    配置文件尽量大写

    # app.py<br>from flask import Flask
     
    app = Flask(__name__)
     
    app.config.from_pyfile("settings.py")  # 加载配置文件setting 
     
    print(app.config['XX'])#打印配置文件中的XX变量
    
    @app.route("/")
    def index():
        return "hello"
     
     
    if __name__ == '__main__':
        app.run()
     
     
    # settings.py
     
    DEBUG = True
    ...  
    

    setting.py

    #方便测试
    try:
        from .localsettings import *
    except ImportError:
        pass
    

    localsettings.py

    用于自己测试

    XX=11
    

    基于类的方式 路径方式导入

    1584016928885

    app.py

    from flask import Flask
     
    app = Flask(__name__)
     
    app.config.from_object("test.settings.TestingConfig")    # 系统环境需能找到的模块路径,默认在app同级目录下
    app.config.from_object("test.settings.Config") #加载
     
    @app.route("/")
    def index():
        return "hello"
     
     
    if __name__ == '__main__':
        app.run()
    

    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  
    

    路由系统

    • 路由的两种写法

      def index():
          return render_template('index.html')
      app.add_url_rule('/index', 'index', index)
      
      
      # 公司里一般用这种方式
      @app.route('/login')
      def login():
          return render_template('login.html')
      
      
    • 路由加载的源码流程

      - 将url和函数打包成为 rule 对象
      - 将rule对象添加到map对象中。
      - app.url_map = map对象
      
      
    • 动态路由

      @app.route('/login')
      def login():
          return render_template('login.html')
          
      @app.route('/login/<name>')
      def login(name):
      	print(type(name))
          return render_template('login.html')
          
      @app.route('/login/<int:name>')
      def login(name):
      	print(type(name))#int类型
          return render_template('login.html')
      
      
    • 支持正则表达式的路由

      from flask import Flask,render_template
      
      app = Flask(__name__)
      
      #-----------------
      固定写法
      from werkzeug.routing import BaseConverter
      class RegConverter(BaseConverter):
          def __init__(self, map, regex):
              super().__init__(map)
              self.regex = regex
      app.url_map.converters['regex'] = RegConverter
      #--------------------
      
      @app.route('/index/<regex("d+"):x1>')
      def index(x1):
          return render_template('index.html')
      
      if __name__ == '__main__':
          app.run()
      
      

    视图

    FBV

    def index():
        return render_template('index.html')
    app.add_url_rule('/index', 'index', index)
    
    
    # 公司里一般用这种方式
    @app.route('/login')
    def login():
        return render_template('login.html')
    
    

    CBV

    from flask import Flask,render_template,views
    
    app = Flask(__name__,)
    
    def test1(func):
        def inner(*args,**kwargs):
            print('before1')
            result = func(*args,**kwargs)
            print('after1')
            return result
        return inner
    
    def test2(func):
        def inner(*args,**kwargs):
            print('before2')
            result = func(*args,**kwargs)
            print('after2')
            return result
        return inner
    
    
    class UserView(views.MethodView):
        methods = ['GET',"POST"]#设置可以通过的请求
    
        decorators = [test1,test2]#设置可以通过的方法
    
    
        def get(self):
            print('get')
            return 'get'
    
        def post(self):
            print('post')
            return 'post'
    
    app.add_url_rule('/user',view_func=UserView.as_view('user')) # endpoint
    
    if __name__ == '__main__':
        app.run()
    
    

    模板

    基本用法

    flask比django更加接近Python。

    from flask import Flask,render_template
    
    app = Flask(__name__,)
    
    def func(arg):
        return '你好' + arg
    
    @app.route('/md')
    def index():
        nums = [11,222,33]
        return render_template('md.html',nums=nums,f=func)
    
    
    if __name__ == '__main__':
        app.run()
    
    

    模板

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>头</h1>
            {% block content %} {% endblock %}
        <h1>底</h1>
    </body>
    </html>
    
    
    

    组件

    <form action="">
        <input type="text">
        <input type="text">
        <input type="text">
        <input type="text">
        <input type="text">
    </form>
    
    

    继承模板 使用组件 使用函数

    {% extends 'layout.html' %}
    
    
    {% block content %}
        <h1>MD</h1>
        {% include 'form.html' %}
        {{ f("汪洋") }}
    {% endblock %}
    
    

    定义全局模板方法

    from flask import Flask,render_template
    
    app = Flask(__name__,)
    
    #在哪个模板都可以用
    @app.template_global() # 使用方法1 {{ func("赵海宇") }}
    def func(arg):
        return '海狗子' + arg
    
    @app.template_filter() #使用方法2 {{ "赵海宇"|x1("孙宇") }}
    def x1(arg,name):
        return '海狗子' + arg + name
    
    
    @app.route('/md/hg')
    def index():
        return render_template('md_hg.html')
    
    if __name__ == '__main__':
        app.run()
    
    

    注意:在蓝图中注册时候,应范围只有本蓝图。

    特殊装饰器 类似中间件

    类似中间件

    from flask import Flask,render_template,request
    
    app = Flask(__name__)
    
    @app.before_request#视图函数前执行
    def f1():
        if request.path == '/login':
            return
        print('f1')
        # return '123'#有返回值就不会往下执行了
    
    @app.after_request#视图函数后执行
    def f10(response):
        print('f10')
        return response
    
    @app.route('/index')
    def index():
        print('index')
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run()
    
    

    多个装饰器

    from flask import Flask,render_template,request
    
    app = Flask(__name__)
    
    @app.before_request
    def f1():
        print('f1')
    
    @app.before_request
    def f2():
        print('f2')
    
    @app.after_request
    def f10(response):
        print('f10')
        return response
    
    @app.after_request
    def f20(response):
        print('f20')
        return response
    
    @app.route('/index')
    def index():
        print('index')
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run()
        app.__call__
    
    

    注意:before_after request可以在蓝图中定义,在蓝图中定义的话,作用域只在本蓝图。

    小细节

    from flask import Flask,render_template
    
    app = Flask(__name__,)
    
    @app.route('/index')
    def index():
        return render_template('index.html')
    
    
    @app.before_request
    def func():
        print('xxx')
    
    #另一种写法
    def x1():
        print('xxx')
    app.before_request(x1)
    
    if __name__ == '__main__':
        app.run()
    
    

    赠送:threading.local

    https://www.cnblogs.com/aaronthon/p/9457330.html

    假如,开了十个线程并且做同样的一件事,他们需要带着自己的数据进来,完成事情后带着自己的数据出去。如果是并发,同时进来,他们的数据就会混乱。

    一般情况,我们加锁就可以了,一个人先进来,先加锁,另一个人过来看到加锁了,就在外面等,等里面的人出来,自己进去加锁,这样就不会出现数据混乱的问题。

    另一种解决方法就是threading.local()来解决问题。

    import time
    import threading
    
    # 当每个线程在执行 val1.xx=1 ,在内部会为此线程开辟一个空间,来存储 xx=1
    # val1.xx,找到此线程自己的内存地址去取自己存储 xx
    val1 = threading.local()
    
    def task(i):
        val1.num = i
        time.sleep(1)
        print(val1.num)
    
    for i in range(4):
        t = threading.Thread(target=task,args=(i,))
        t.start()
    
    
  • 相关阅读:
    Nmon 性能:分析 AIX 和 Linux 性能的免费工具
    libvirt(virsh命令总结)
    Linux之shell编程基础
    Shell之sed命令
    linux shell基础
    ubuntu apt-get 遇到的问题
    JavaScript之面向对象学九(原型式继承和寄生式继承)
    JavaScript之apply()和call()的区别
    JavaScript之面向对象学习八(继承)
    JavaScript之面向对象学习七(动态原型模式、寄生构造函数模式、稳妥构造函数模式创建自定义类型)
  • 原文地址:https://www.cnblogs.com/saoqiang/p/12482871.html
Copyright © 2020-2023  润新知