zoukankan      html  css  js  c++  java
  • flask

    flask 进阶

    上下文管理和SQLHelper

    ```python
    import pymysql
    from DBUtils.PooledDB import PooledDB
    
    class SqlHelper(object):
        def __init__(self):
            self.pool = PooledDB(
                creator=pymysql,  # 使用链接数据库的模块
                maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
                mincached=2,  # 初始化时,链接池中至少创建的链接,0表示不创建
                blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
                ping=0,
                # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
                host='127.0.0.1',
                port=3306,
                user='root',
                password='222',
                database='cmdb',
                charset='utf8'
            )
    
        def open(self):
            conn = self.pool.connection()
            cursor = conn.cursor()
            return conn,cursor
    
        def close(self,cursor,conn):
            cursor.close()
            conn.close()
    
        def fetchall(self,sql, *args):
            """ 获取所有数据 """
            conn,cursor = self.open()
            cursor.execute(sql, args)
            result = cursor.fetchall()
            self.close(conn,cursor)
            return result
    
        def fetchone(self,sql, *args):
            """ 获取所有数据 """
            conn, cursor = self.open()
            cursor.execute(sql, args)
            result = cursor.fetchone()
            self.close(conn, cursor)
            return result
    
        def __enter__(self):
            return self.open()[1]
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print(exc_type, exc_val, exc_tb)
    
    
    db = SqlHelper()
    ```
    

    概要

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

    详细

    1.wsgi 找源码的流程

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

    2.flask对象

    静态文件的处理。

    推荐

    from flask import Flask,render_template
    
    app = Flask(__name__,template_folder='templates',static_folder='static')
    
    @app.route('/index')
    def index():
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run()
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>首页</h1>
        <img src="/static/xx/xx/mm.jpg" />
        
        <!-- 建议 -->
        <img src="{{ url_for('static',filename='xx/xx/mm.jpg')}}" />
    </body>
    </html>
    

    3.配置文件

    3.1 基于全局变量

    3.2 基于类的方式

    4.路由系统

    • 路由的两种写法

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

    5.视图

    5.1 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')
    

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

    6.模板

    6.1 基本用法

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

    6.2 定义全局模板方法

    from flask import Flask,render_template
    
    app = Flask(__name__,)
    
    @app.template_global() #  {{ func("赵海宇") }}
    def func(arg):
        return '海狗子' + arg
    
    @app.template_filter() # {{ "赵海宇"|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()
    

    注意:在蓝图中注册时候,应用返回只有本蓝图。

    7.特殊装饰器

    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可以在蓝图中定义,在蓝图中定义的话,作用域只在本蓝图。

    8.小细节

    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

    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()
    
  • 相关阅读:
    最方便建立进程池,线程池的方法
    python并发编程之多线程
    Cpython解释器支持的进程与线程
    进程与线程理论基础
    爬虫关于高性能方面
    Python中 and,or 的计算规则
    存储库之——MongoDB
    解析库之——beautifulsoup
    破解极验滑动验证码
    爬取拉勾网示例
  • 原文地址:https://www.cnblogs.com/zgboy/p/13447783.html
Copyright © 2011-2022 走看看