zoukankan      html  css  js  c++  java
  • 无用之flask学习

    一、认识flask

      1、短小精悍、可扩展性强 的一个web框架

        注意:上下文管理机制

      2、依赖wsgi:werkzurg

    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)

    注意__init__和__call__的区别:

    class Foo():
        def __init__(self):
            print('init')
        def __call__(self, *args, **kwargs):
            print('call')
    a = Foo()
    a()
    
    #init
    #call

    一个简单的flask代码

    from flask import Flask
    app = Flask(__name__)
    @app.route(
    '/index') def index(): return 'hello world' if __name__ == '__main__': app.run('local

    二、一个有登录功能的flask例子

      1、template可以类似django修改

      2、static有两种方式,

         A:  a、 static_folder="staticccc"  b、将static文件夹命名为 staticccc   c、img引用的时候用staticccc/xxxxx
        B: a、 static_url_path='/vvvvv' b、 img引用的时候用 /vvvvv/xxxxx
    from flask import Flask,render_template,request,redirect,session
    
    # app = Flask(__name__,template_folder="templates",static_folder="staticccc",static_url_path='/vvvvv')
    app = Flask(__name__,template_folder="templates",static_folder="static")
    app.secret_key = 'asdfasdf'
    
    @app.route('/login',methods=["GET","POST"])
    def login():
        if request.method == 'GET':
            return render_template('login.html')
      # request.args 获取的是get的信息 user
    = request.form.get('user') #获取的是post的信息 pwd = request.form.get('pwd') if user == 'oldboy' and pwd == '666': session['user'] = user return redirect('/index') return render_template('login.html',error='用户名或密码错误') # return render_template('login.html',**{"error":'用户名或密码错误'}) @app.route('/index') def index(): user = session.get('user') if not user: return redirect('/login') return render_template('index.html') if __name__ == '__main__': app.run()

    index.html

    <body>
        <h1>欢迎使用</h1>
        <img src="/static/111.png" alt="">
    </body>

    login.html

    <body>
        <h1>用户登录</h1>
        <form method="post">
            <input type="text" name="user">
            <input type="password" name="pwd">
            <input type="submit" value="提交">{{error}}
        </form>
    </body>

     三、flask基础

    1、配置文件
    
    2、路由系统
    
    3、视图
    
    4、请求相关
    
    5、响应
    
    6、模板渲染
    
    7、session
    
    8、闪现
    
    9、中间件
    
    10、蓝图(blueprint)
    
    11、特殊装饰器

    1、django和flask的区别

      django:是一个大而全的框架,内部提供了很多组件,如orm,admin,forms,分页等很多方便的组件,只需在配置里配置下就可以了

      flask: 是一个轻量级的框架,短小精悍,可扩展性很强,适用于开发小的网站,他提供了很多第三方的组件,只需要跟这些组件结合起来也可以创造一个类似django的框架 ,可定制型强

      就我个人而言,我比较偏向于。。。。。

    2、flask和django最大的不同点

      request/session,     

        django需要导入,参数;flask直接调用

    3、flask知识点

      --模板+静态文件  ,app=Flask(__name__,......)

      --路由

        @app.route('/index',methods=['GET'])

      --请求

        request.form

        request.args

        request.method

      --响应

        “”

        render

        redirect

      --session

        session['xx']=123

        session.get('xx')

    4、配置文件导入原理,  ----即给一个路径‘settings.Foo’,可以找到类并获取去其中的大写的静态字段

      settings.py

    class Foo():
        DEBUG = True
        TEXT = True

    test.py

    import importlib
    
    path = 'settings.Foo'
    p,c = path.rsplit('.',maxsplit=1)
    m = importlib.import_module(p)
    cls = getattr(m,c)
    
    for key in dir(cls):
        if key.isupper():
            print(key,getattr(cls,key))

    #DEBUG True
    #TEXT True

    5、配置文件使用

    app.config.from_object('settings.Dev')

    test.py

    from flask import Flask
    app = Flask(__name__)
    
    print(app.config)
    app.config.from_object('settings.Dev')
    print(app.config)
    
    if __name__ == '__main__':
        app.run()

    settings.py

    class Base(object):     #无论哪种环境都需要的类
        XX = 123
    
    class Pro(Base):   #生产环境
        DEBUG = False
    
    class Dev(Base):    #开发环境
        DEBUG = True

    6、路由系统

     实例:

    from flask import Flask,url_for
    app = Flask(__name__)
    
    app.route('/index/<int:nid>',methods=['GET','POST'])
    def index(nid):
        print(url_for("index",nid=888))

    知识点:

     ---endpoint,反向生成URL,默认函数名
    
     ---url_for('endpoint')
    
     ---动态路由:
    
      /index/<int:nid>
    
      def index(nid):
    
        print(nid)
        return "index"

    7、请求和响应相关

      请求相关消息

     # 请求相关信息
            # request.method
            # request.args
            # request.form
            # request.values
            # request.cookies
            # request.headers
            # request.path
            # request.full_path
            # request.script_root
            # request.url
            # request.base_url
            # request.url_root
            # request.host_url
            # request.host
            # request.files

      响应相关消息

        A、响应体

       return render_template('xxx.html')
        return redirect('/index')
        return 'xxx'
        return jsonify({'k1':'v1'})

        B、响应头

       obj = make_response('asdf')
        obj.headers['xxxx'] = '123'
        obj.set_cookie('key','value')
        return obj

    8、学生管理系统

      版本一几乎不用,版本二在某些函数前做定制,版本在全局使用的时候用到

            版本一:
                @app.route('/index')
                def index():
                    if not session.get('user'):
                        return redirect(url_for('login'))
                    return render_template('index.html',stu_dic=STUDENT_DICT)
            版本二:
                import functools
                def auth(func):
                    @functools.wraps(func)
                    def inner(*args,**kwargs):
                        if not session.get('user'):
                            return redirect(url_for('login'))
                        ret = func(*args,**kwargs)
                        return ret
                    return inner
            
                @app.route('/index')
                @auth
                def index():
                    return render_template('index.html',stu_dic=STUDENT_DICT)
            
                应用场景:比较少的函数中需要额外添加功能。
                
            版本三:before_request
                @app.before_request
                def xxxxxx():
                    if request.path == '/login':
                        return None
    
                    if session.get('user'):
                        return None
    
                    return redirect('/login')

    app.py

    from flask import Flask,render_template,request,redirect,session,url_for,jsonify,make_response,Markup,flash,get_flashed_messages
    
    app = Flask(__name__)
    
    app.config.from_object("settings.DevelopmentConfig")
    
    STUDENT_DICT = {
        1:{'name':'王龙泰','age':38,'gender':''},
        2:{'name':'小东北','age':73,'gender':''},
        3:{'name':'田硕','age':84,'gender':''},
    }
    
    @app.before_request
    def xxxxxx():
        if request.path == '/login':
            return None
    
        if session.get('user'):
            return None
    
        return redirect('/login')
    
    
    
    @app.route('/login',methods=["GET","POST"])
    def login():
        print('login')
        if request.method == 'GET':
            return render_template('login.html')
        user = request.form.get('user')
        pwd = request.form.get('pwd')
        if user == 'oldboy' and pwd == '666':
            session['user'] = user
            return redirect('/index')
        return render_template('login.html',error='用户名或密码错误')
    
    
    @app.route('/index')
    def index():
        print('index')
        return render_template('index.html',stu_dic=STUDENT_DICT)
    
    @app.route('/delete/<int:nid>')
    def delete(nid):
    
        del STUDENT_DICT[nid]
        return redirect(url_for('index'))
    
    @app.route('/detail/<int:nid>')
    def detail(nid):
        info = STUDENT_DICT[nid]
        return render_template('detail.html',info=info)
    
    
    if __name__ == '__main__':
        app.run()

    login.html

    <body>
        <h1>用户登录</h1>
        <form method="post">
            <input type="text" name="user">
            <input type="password" name="pwd">
            <input type="submit" value="提交">{{error}}
        </form>

    index.html

    <body>
        <h1>学生列表</h1>
        <table border="1">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>性别</th>
                    <th>选项</th>
                </tr>
            </thead>
            <tbody>
                {% for k,v in  stu_dic.items() %}
                    <tr>
                        <td>{{k}}</td>
                        <td>{{v.name }}</td>
                        <td>{{v.age}}</td>
                        <td>{{v.gender}}</td>
                        <td>
                            <a href="/detail/{{k}}">查看详细</a>
                            |
                            <a href="/delete/{{k}}">删除</a>
    
                        </td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    </body>

    detail.html

    <body>
        <h1>学生详细</h1>
        <ul>
    
            {% for item in info.values() %}
            <li>{{item}}</li>
            {% endfor %}
        </ul>
    </body>

     9、模板

    6. 模板渲染 
            - 基本数据类型:可以执行python语法,如:dict.get()  list['xx']
            - 传入函数
                - django,自动执行
                - flask,不自动执行
            - 全局定义函数
                @app.template_global()
                def sb(a1, a2):
                    # {{sb(1,9)}}
                    return a1 + a2
    
                @app.template_filter()
                def db(a1, a2, a3):
                    # {{ 1|db(2,3) }}
                    return a1 + a2 + a3
            - 模板继承
                layout.html
                    <!DOCTYPE html>
                    <html lang="zh-CN">
                    <head>
                        <meta charset="UTF-8">
                        <title>Title</title>
                        <meta name="viewport" content="width=device-width, initial-scale=1">
                    </head>
                    <body>
                        <h1>模板</h1>
                        {% block content %}{% endblock %}
                    </body>
                    </html>
                
                tpl.html
                    {% extends "layout.html"%}
    
    
                    {% block content %}
                        {{users.0}}
                        
    
                    {% endblock %}    
            - include 
        
        
                {% include "form.html" %}
                
                
                form.html 
                    <form>
                        asdfasdf
                        asdfasdf
                        asdf
                        asdf
                    </form>
            - 宏
                {% macro ccccc(name, type='text', value='') %}
                    <h1>宏</h1>
                    <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
                    <input type="submit" value="提交">
                {% endmacro %}
    
                {{ ccccc('n1') }}
    
                {{ ccccc('n2') }}
                
            - 安全
                - 前端: {{u|safe}}
                - 前端: MarkUp("asdf")
            

    10、session

    当请求刚到来:flask读取cookie中session对应的值:eyJrMiI6NDU2LCJ1c2VyIjoib2xkYm95,将该值解密并反序列化成字典,放入内存以便视图函数使用。   视图函数:
          @app.route('/ses')
          def ses():
             session['k1'] = 123
             session['k2'] = 456
             del session['k1']
    
             return "Session"
    
      
                   
                session['xxx'] = 123
                session['xxx']
                
       当请求结束时,flask会读取内存中字典的值,进行序列化+加密,写入到用户cookie中。

    settings.py

    from datetime import timedelta
    class Config(object):
        DEBUG = False
        TESTING = False
        SECRET_KEY = "asdfasdfas23"
        DATABASE_URI = 'sqlite://:memory:'
    
        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
        PERMANENT_SESSION_LIFETIME = timedelta(hours=1)

    11、闪现

    在session中存储一个数据,读取时通过pop将数据移除。
    from flask import Flask,flash,get_flashed_messages
    @app.route('/page1')
    def page1():
    
       flash('临时数据存储','error')
       flash('sdfsdf234234','error')
       flash('adasdfasdf','info')
    
       return "Session"
    
    @app.route('/page2')
    def page2():
       print(get_flashed_messages(category_filter=['error']))
       return "Session"

    12、中间件

        - call方法什么时候出发?
                - 用户发起请求时,才执行。
            - 任务:在执行call方法之前,做一个操作,call方法执行之后做一个操作。
                class Middleware(object):
                    def __init__(self,old):
                        self.old = old
    
                    def __call__(self, *args, **kwargs):
                        ret = self.old(*args, **kwargs)
                        return ret
    
    
                if __name__ == '__main__':
                    app.wsgi_app = Middleware(app.wsgi_app)
                    app.run()

     13、特殊装饰器

        1. before_request
            
            2. after_request
            
                示例:
                    from flask import Flask
                    app = Flask(__name__)
    
    
                    @app.before_request
                    def x1():
                        print('before:x1')
                        return ''
    
                    @app.before_request
                    def xx1():
                        print('before:xx1')
    
    
                    @app.after_request
                    def x2(response):
                        print('after:x2')
                        return response
    
                    @app.after_request
                    def xx2(response):
                        print('after:xx2')
                        return response
    
    
    
                    @app.route('/index')
                    def index():
                        print('index')
                        return "Index"
    
    
                    @app.route('/order')
                    def order():
                        print('order')
                        return "order"
    
    
                    if __name__ == '__main__':
    
                        app.run()
            
            3. before_first_request
            
                from flask import Flask
                app = Flask(__name__)
    
                @app.before_first_request
                def x1():
                    print('123123')
    
    
                @app.route('/index')
                def index():
                    print('index')
                    return "Index"
    
    
                @app.route('/order')
                def order():
                    print('order')
                    return "order"
    
    
                if __name__ == '__main__':
    
                    app.run()
    
            
            4. template_global
            
            5. template_filter
            
            6. errorhandler
                @app.errorhandler(404)
                def not_found(arg):
                    print(arg)
                    return "没找到"

    14、内容慧谷

        1. django和flask区别?
        2.什么是wsgi?
            web服务网关接口,wsgi是一个协议,实现该写一个的模块:
                - wsgiref
                - werkzeug
            实现其协议的模块本质上就是socket服务端用于接收用户请求,并处理。
            一般web框架基于wsgi实现,这样实现关注点分离。
            
            wsgiref示例:
                from wsgiref.simple_server import make_server
     
                def run_server(environ, start_response):
                    start_response('200 OK', [('Content-Type', 'text/html')])
                    return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]
                 
                 
                if __name__ == '__main__':
                    httpd = make_server('127.0.0.1', 8000, run_server)
                    httpd.serve_forever()
            
            werkzeug示例:
                from werkzeug.wrappers import Response
                from werkzeug.serving import run_simple
    
                def run_server(environ, start_response):
                    response = Response('hello')
                    return response(environ, start_response)
    
                if __name__ == '__main__':
                    run_simple('127.0.0.1', 8000, run_server)
    
            Flask源码入口:
                from werkzeug.wrappers import Response
                from werkzeug.serving import run_simple
    
                class Flask(object):
                    def __call__(self,environ, start_response):
                        response = Response('hello')
                        return response(environ, start_response)
    
                    def run(self):
                        run_simple('127.0.0.1', 8000, self)
    
    
    
                app = Flask()
    
                if __name__ == '__main__':
                    app.run()
        
        3. Flask提供功能
            - 配置文件
                - 所有配置都在app.config中
                - app.config["xx"] = 123
                - app.config.from_object("类的路径")
                - 应用:importlib、getattr
                    - django中间件
                    - rest framework全局配置
            - session 
                - 加密后放置在用户浏览器的cookie中。
                - 流程:
                    - 请求到来
                    - 视图函数
                    - 请求结束
                - 配置文件 
            - 闪现
                - 基于session实现
            - 路由
                - 装饰器(带参数)
                - 自定义装饰器放下面
                - 参数 
                - url_for
            - 视图
                - FBV
            - 请求和响应
                - 请求:request
                - 响应: 4种
            - 模板
                - ...
            - 特殊装饰器
                - before_first_request
                - before_request
                - after_request
                - template_global()
                - template_filter()
                - errorhandler(404)
            - 中间件    
        
    今日内容:
        1. 路由+视图
        2. session实现原理(源码)
        3. 蓝图
        4. threading.local
        5. 上下文管理(第一次)
        
        

     15、路由+视图

    a. 路由设置的两种方式:
                @app.route('/xxx')
                    def index():
                        return "index"
    
                
                def index():
                    return "index"
                app.add_url_rule("/xxx",None,index)
                
                注意事项:
                    - 不用让endpoint重名
                    - 如果重名函数也一定要相同。

    16、路由+视图之 参数

        rule,                       URL规则
                view_func,                  视图函数名称
                endpoint=None,              名称,用于反向生成URL,即: url_for('名称')
                methods=None,               允许的请求方式,如:["GET","POST"]
                strict_slashes=None,        对URL最后的 / 符号是否严格要求,
                redirect_to=None,           重定向到指定地址
    
                defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
                subdomain=None,             子域名访问

    实例

    需要去hosts文件里将 127.0.0.1   wupeiqi.com,将ip和域名配置下
    from flask import Flask, views, url_for
    
    app = Flask(import_name=__name__)
    app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    """
    127.0.0.1   wupeiqi.com
    127.0.0.1   web.wupeiqi.com
    127.0.0.1   admin.wupeiqi.com
    
    """
    
    # http://admin.wupeiqi.com:5000/
    @app.route("/", subdomain="admin")
    def admin_index():
        return "admin.your-domain.tld"
    
    
    # http://web.wupeiqi.com:5000/
    @app.route("/", subdomain="web")
    def web_index():
        return "web.your-domain.tld"
    
    
    # http://sdsdf.wupeiqi.com:5000/
    # http://sdfsdf.wupeiqi.com:5000/
    # http://asdf.wupeiqi.com:5000/
    
    @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()

    17、路由+视图之 CBV

        import functools
                from flask import Flask,views
                app = Flask(__name__)
    
    
                def wrapper(func):
                    @functools.wraps(func)
                    def inner(*args,**kwargs):
                        return func(*args,**kwargs)
    
                    return inner
    
    
                class UserView(views.MethodView):
                    methods = ['GET']
                    decorators = [wrapper,]
    
                    def get(self,*args,**kwargs):
                        return 'GET'
    
                    def post(self,*args,**kwargs):
                        return 'POST'
    
                app.add_url_rule('/user',None,UserView.as_view('uuuu'))
    
                if __name__ == '__main__':
                    app.run()

    18、路由+视图之 自定义正则

        from flask import Flask,url_for
    
                app = Flask(__name__)
    
                # 步骤一:定制类
                from werkzeug.routing import BaseConverter
                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['reg'] = RegexConverter
    
                """
                1. 用户发送请求
                2. flask内部进行正则匹配
                3. 调用to_python(正则匹配的结果)方法
                4. to_python方法的返回值会交给视图函数的参数
    
                """
    
                # 步骤三:使用自定义正则
                @app.route('/index/<reg("d+"):nid>')
                def index(nid):
                    print(nid,type(nid))
    
                    print(url_for('index',nid=987))
                    return "index"
    
                if __name__ == '__main__':
                    app.run()

    19、session原理

    session流程图(加分项)

    20、蓝图

        目标:给开发者提供目录结构
            
            其他:
                - 自定义模板、静态文件
                - 某一类url添加前缀        -----用以加版本号如,v1....
                - 给一类url添加before_request

    A、小蓝图(template、views放一起,大蓝图类似django分布)目录

    B、manage.py

    from crm import create_app
    
    app = create_app()
    
    if __name__ == '__main__':
        app.run()

    init.py

    from flask import Flask
    from .views.account import ac
    from .views.user import uc
    
    def create_app():
    
        app = Flask(__name__)
    
        # @app.before_request
        # def x1():
        #     print('app.before_request')
    
        app.register_blueprint(ac)
        app.register_blueprint(uc,url_prefix='/api')
        return app

    accout.py

    from flask import Blueprint,render_template
    
    ac = Blueprint('ac',__name__)
    
    @ac.before_request
    def x1():
        print('app.before_request')
    
    
    @ac.route('/login')
    def login():
        return render_template('login.html')
    
    
    @ac.route('/logout')
    def logout():
        return 'Logout'

    user.py

    from flask import Blueprint
    
    uc = Blueprint('uc',__name__)
    
    
    @uc.route('/list')
    def list():
        return 'List'
    
    
    @uc.route('/detail')
    def detail():
        return 'detail'

    21、threading.local【和flask无任何关系】

     flask里local()原码

    作用:为每个线程创建一个独立的空间,使得线程对自己的空间中的数据进行操作(数据隔离)。
                import threading
                from threading import local
                import time
    
                obj = local()
    
    
                def task(i):
                    obj.xxxxx = i
                    time.sleep(2)
                    print(obj.xxxxx,i)
    
                for i in range(10):
                    t = threading.Thread(target=task,args=(i,))
                    t.start()
    
            问题:
                - 如何获取一个线程的唯一标记? threading.get_ident()
                - 根据字典自定义一个类似于threading.local功能?
                    import time
                    import threading
    
                    DIC = {}
    
                    def task(i):
                        ident = threading.get_ident()
                        if ident in DIC:
                            DIC[ident]['xxxxx'] = i
                        else:
                            DIC[ident] = {'xxxxx':i }
                        time.sleep(2)
    
                        print(DIC[ident]['xxxxx'],i)
    
                    for i in range(10):
                        t = threading.Thread(target=task,args=(i,))
                        t.start()
                    
                - 根据字典自定义一个为每个协程开辟空间进行存取数据。
                
                    import time
                    import threading
                    import greenlet
    
                    DIC = {}
    
                    def task(i):
                        
                        # ident = threading.get_ident()
                        ident = greenlet.getcurrent()
                        if ident in DIC:
                            DIC[ident]['xxxxx'] = i
                        else:
                            DIC[ident] = {'xxxxx':i }
                        time.sleep(2)
    
                        print(DIC[ident]['xxxxx'],i)
    
                    for i in range(10):
                        t = threading.Thread(target=task,args=(i,))
                        t.start()
                
                - 通过getattr/setattr 构造出来 threading.local的加强版(协程)
                    import time
                    import threading
                    try:
                        import greenlet
                        get_ident =  greenlet.getcurrent
                    except Exception as e:
                        get_ident = threading.get_ident
    
                    class Local(object):
                        DIC = {}
    
                        def __getattr__(self, item):
                            ident = get_ident()
                            if ident in self.DIC:
                                return self.DIC[ident].get(item)
                            return None
    
                        def __setattr__(self, key, value):
                            ident = get_ident()
                            if ident in self.DIC:
                                self.DIC[ident][key] = value
                            else:
                                self.DIC[ident] = {key:value}
                            
    
                    obj = Local()
    
                    def task(i):
                        obj.xxxxx = i
                        time.sleep(2)
                        print(obj.xxxxx,i)
    
                    for i in range(10):
                        t = threading.Thread(target=task,args=(i,))
                        t.start()

    22、上下文管理

    请求到来时候:
                # ctx = RequestContext(self, environ) # self是app对象,environ请求相关的原始数据
                # ctx.request = Request(environ)
                # ctx.session = None
                
                # 将包含了request/session的ctx对象放到“空调”
                    {
                        1232:{ctx:ctx对象}
                        1231:{ctx:ctx对象}
                        1211:{ctx:ctx对象}
                        1111:{ctx:ctx对象}
                        1261:{ctx:ctx对象}
                    }
                    
            视图函数:
                from flask import reuqest,session 
                
                request.method 
                
                
            请求结束:
                根据当前线程的唯一标记,将“空调”上的数据移除。

    23、上下文管理前戏

    1、偏函数

    # by luffycity.com
    import functools
    
    
    def index(a1,a2):
        return a1 + a2
    
    # 原来的调用方式
    # ret = index(1,23)
    # print(ret)
    
    # 偏函数,帮助开发者自动传递参数
    new_func = functools.partial(index,666)
    ret = new_func(1)
    print(ret)

    2、执行父类方法

    - super和执行类的区别?
                """
                class Base(object):
    
                    def func(self):
                        print('Base.func')
    
                class Foo(Base):
    
                    def func(self):
                        # 方式一:根据mro的顺序执行方法
                        # super(Foo,self).func()
                        # 方式二:主动执行Base类的方法
                        # Base.func(self)
    
                        print('Foo.func')
    
    
                obj = Foo()
                obj.func()
                """
                #################################### 
                class Base(object):
    
                    def func(self):
                        super(Base, self).func()
                        print('Base.func')
    
                class Bar(object):
                    def func(self):
                        print('Bar.func')
    
                class Foo(Base,Bar):
                    pass
    
                # 示例一
                # obj = Foo()
                # obj.func()
                # print(Foo.__mro__)
    
                # 示例二
                # obj = Base()
                # obj.func()

    3、面向对象中特殊方法 setattr/getattr注意事项:

                class Foo(object):
                    def __init__(self):
                        # self.storage = {}
                        object.__setattr__(self,'storage',{})
    
                    def __setattr__(self, key, value):
                        print(key,value,self.storage)
                        
    
    
                obj = Foo()
                obj.xx = 123

    4、基于列表实现栈 

        class Stack(object):
    
                    def __init__(self):
                        self.data = []
    
                    def push(self,val):
                        self.data.append(val)
    
                    def pop(self):
                        return self.data.pop()
                    
                    def top(self):
                        return self.data[-1]
    
                _stack = Stack()
    
                _stack.push('佳俊')
                _stack.push('咸鱼')
    
                print(_stack.pop())
                print(_stack.pop())

    24、flask-session 

        pip3 install flask-session 
            
            掌握:
                - 使用
                    # by luffycity.com
                    import redis
                    from flask import Flask,request,session
                    from flask.sessions import SecureCookieSessionInterface
                    from flask_session import Session
    
                    app = Flask(__name__)
    
                    # app.session_interface = SecureCookieSessionInterface()
                    # app.session_interface = RedisSessionInterface()
                    app.config['SESSION_TYPE'] = 'redis'
                    app.config['SESSION_REDIS'] = redis.Redis(host='140.143.227.206',port=6379,password='1234')
                    Session(app)
    
                    @app.route('/login')
                    def login():
                        session['user'] = 'alex'
                        return 'asdfasfd'
    
                    @app.route('/home')
                    def index():
                        print(session.get('user'))
    
                        return '...'
    
    
                    if __name__ == '__main__':
                        app.run()
                - 原理:
                    - session数据保存到redis
                        session:随机字符串1:q23asifaksdfkajsdfasdf
                        session:随机字符串2:q23asifaksdfkajsdfasdf
                        session:随机字符串3:q23asifaksdfkajsdfasdf
                        session:随机字符串4:q23asifaksdfkajsdfasdf
                        session:随机字符串5:q23asifaksdfkajsdfasdf
                    - 随机字符串返回给用户。
                        随机字符串
                    
                    
                    源码:
                        from flask_session import RedisSessionInterface
                    

    25、判断是否是函数和方法

    def func():
        pass
    
    
    class Foo(object):
    
        def func(self):
            pass
    
    # 执行方式一
    # obj = Foo()
    # obj.func() # 方法
    
    # 执行方式二
    # Foo.func(123) # 函数
    
    from types import FunctionType,MethodType
    
    # obj = Foo()
    # print(isinstance(obj.func,FunctionType)) # False
    # print(isinstance(obj.func,MethodType))   # True
    
    
    print(isinstance(Foo.func,FunctionType)) # True
    print(isinstance(Foo.func,MethodType))   # False

    26、redis安装下载地址:https://github.com/MicrosoftArchive/redis/releases

      redis-desktop manager 0.9.3.817.exe

     27、code management system

      1、注意设计表的时候,自增和外键的id类型要一致

       2、work

    内容详细:
        - 代码统计
        
        - 数据库连接池:    
            pip3 install DBUtils
        
        注意:
            - 使用数据库连接池
            - 封装SQLHelper
        
    作业:
        1. 功能完善
        2. BootStrap 模板
        3. 详细页面: http://127.0.0.1:5000/detail/1  -> 折线图
        4. 用户列表:
                    - 柱状图
                    - 表格
                    PS: select user_id,sum(line) from record group by user_id + 连表查询到用户姓名
                        
        

     28、review

    第一部分:Flask
            1. 谈谈你对django和flask的认识?
            
            2. Flask基础:
                - 配置文件:反射+importlib
                - 路由系统:
                    - 装饰器 @app.route()
                    - 参数:
                        - url
                        - endpoint
                        - methods
                    - 加装饰器
                        - endpoint默认是函数名
                        - functools.wraps(func)  + functools.partial
                    - 写路由两种方式:
                        - 装饰器
                        - add_url_rule
                    - 自定义支持正则的URL
                - session 
                - 蓝图 
                    - 目录结构划分
                    - 前缀
                    - 特殊装饰器
            3. 上下文管理 
                - threading.local
                    - 为每个线程开辟空间,使得线程之间进行数据隔离。
                    - 应用:DBUtils中为每个线程创建一个数据库连接时使用。
                - 面向对象特殊方法:
                    - getattr
                    - setattr
                    - delattr
                - 偏函数
                - 单例模式
                - 请求上下文流程:
                    - 班级示例:
                    - 源码流程:
                        - __call__
                        - wsgi_app
                            - ctx = RequestContext(): 封装= 请求数据+空session
                            - ctx.push() : 将ctx传给LocalStack对象,LocalStack再将数据传给Local存储起来。
                                           问题:Local中是如何存储?
                                                __storage__ = {
                                                    1231:{}
                                                }
                                            问题:LocalStack作用?
                                                __storage__ = {
                                                    1231:{stack:[ctx] }
                                                }
                        - 视图函数:再次去获取
                    - 关闭
            
            
            4. 第三方组件:
                1. flask-session 
                2. DBUtils 

    29、数据库&前端

        1. 什么是响应式布局?
                @media属性
            2. MySQL数据库
                - 引擎:
                    - innodb
                        - 支持事务
                        -- 行锁
                            - 表锁
                            - 示例:
                                - 终端:
                                    begin;
                                    select xx from xx for update;
                                    commit;
                                - pymysql
                                    cursor.execute('select * from xx for update')
                                - django
                                    with trancation.automic():
                                        models.User.objects.all().for_update()
                    - mysaim
                        - 不支持事务
                        -- 表锁 
                        - 快

    30、上下文管理

    知识点

    # by luffycity.com
    
    class Foo(object):
    
        def __str__(self):
            return 'asdf'
    
        def __getattr__(self, item):
            return "999"
    
        def __getitem__(self, item):
            return '87'
    
        def __add__(self, other):
            return other + 1
    
    obj = Foo()
    
    print(obj)
    print(obj.x)
    print(obj['x1'])
    
    print(obj + 7)
    上下文
    1. 上下文管理:LocalProxy对象
        2. 上下文管理:
                - 请求上下文:request/session
                - App上下文: app/g
    from flask import Flask,request,session
    
    app = Flask(__name__)
    
    
    @app.route('/index')
    def index():
        # 1. request是LocalProxy对象
        # 2. 对象中有method、执行__getattr__
        print(request.method)
        # request['method']
        # request + 1
    
        # 1. session是LocalProxy对象
        # 2. LocalProxy对象的__setitem__
        session['x'] = 123
    
        return "Index"
    
    
    if __name__ == '__main__':
        app.run()
        # app.__call__
        # app.wsgi_app
    
    """
    第一阶段:请求到来
        将request和Session相关数据封装到ctx=RequestContext对象中。
        再通过LocalStack将ctx添加到Local中。
        __storage__ = {
            1231:{'stack':[ctx(request,session)]}
        }
    第二阶段:视图函数中获取request或session
        方式一:直接找LocalStack获取
                from flask.globals import _request_ctx_stack
                print(_request_ctx_stack.top.request.method)
                
        方式二:通过代理LocalProxy(小东北)获取
                from flask import Flask,request
                print(request.method)
                
    """

    详细

    容详细:
        1. 上下文管理:LocalProxy对象
        2. 上下文管理:
                - 请求上下文(ctx=RequestContext()):request/session
                -  App上下文(app_ctx=AppContext()): app/g
                
            - 程序启动:
                两个Local:
                    local1 = {
                    
                    }
                    
                    local2 = {
                    
                    }
            
                两个LocalStack:
                    _request_ctx_stack
                    _app_ctx_stack
            - 请求到来
                对数据进行封装:
                    ctx = RequestContext(request,session)
                    app_ctx = AppContext(app,g)
                保存数据:
                    将包含了(app,g)数据的app_ctx对象,利用 _app_ctx_stack(贝贝,LocalStack())将app_ctx添加到Local中
                        storage = {
                            1231:{stack:[app_ctx(app,g),]}
                        }
                    将包含了request,session数据的ctx对象,利用_request_ctx_stack(刘淞,LocalStack()),将ctx添加到Local中
                        storage = {
                            1231:{stack:[ctx(request,session),]}
                        }
                        
            - 视图函数处理:
                
                
                from flask import Flask,request,session,current_app,g
    
                app = Flask(__name__)
    
    
                @app.route('/index')
                def index():
                    # 去请求上下文中获取值 _request_ctx_stack
                    request.method # 找小东北获取值
                    session['xxx'] # 找龙泰获取值
                    
                    # 去app上下文中获取值:_app_ctx_stack 
                    print(current_app)
                    print(g)
                    
                    return "Index"
    
    
                if __name__ == '__main__':
                    app.run()
                    app.wsgi_app
            
            - 结束
                _app_ctx_stack.pop()
                _request_ctx_stack.pop()
    
                
                
            问题:
                1. Flask中g的生命周期?
                2. g和session一样吗?
                3. g和全局变量一样吗?
                    

    31、wtforms

    基本使用

    from flask import Flask,request,render_template,session,current_app,g,redirect
    from wtforms import Form
    from wtforms.fields import simple
    from wtforms.fields import html5
    from wtforms.fields import core

    from wtforms import widgets
    from wtforms import validators

    app = Flask(__name__)


    class LoginForm(Form):
    name = simple.StringField(
    validators=[
    validators.DataRequired(message='用户名不能为空.'),
    # validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
    ],
    widget=widgets.TextInput(),
    render_kw={'placeholder':'请输入用户名'}
    )
    pwd = simple.PasswordField(
    validators=[
    validators.DataRequired(message='密码不能为空.'),
    # validators.Length(min=8, message='用户名长度必须大于%(min)d'),
    # validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[$@$!%*?&])[A-Za-zd$@$!%*?&]{8,}",
    # message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符')

    ],
    render_kw={'placeholder':'请输入密码'}
    )


    @app.route('/login',methods=['GET','POST'])
    def login():
    if request.method == "GET":
    form = LoginForm()
    # print(form.name,type(form.name)) # form.name是StringField()对象, StringField().__str__
    # print(form.pwd,type(form.pwd)) # form.pwd是PasswordField()对象,PasswordField().__str__
    return render_template('login.html',form=form)

    form = LoginForm(formdata=request.form)
    if form.validate():
    print(form.data)
    return redirect('https://www.luffycity.com/home')
    else:
    # print(form.errors)
    return render_template('login.html', form=form)



    import helper
    class UserForm(Form):
    city = core.SelectField(
    label='城市',
    choices=(),
    coerce=int
    )
    name = simple.StringField(label='姓名')

    def __init__(self,*args,**kwargs):
    super(UserForm,self).__init__(*args,**kwargs)

    self.city.choices=helper.fetch_all('select id,name from tb1',[],type=None)


    @app.route('/user')
    def user():
    if request.method == "GET":
    #form = UserForm(data={'name':'alex','city':3}) #默认传入值,在编辑用户界面适合用a
    form = UserForm()
    return render_template('user.html',form=form)


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

    login.html

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        <form method="post" novalidate>
            <p>用户名:{{form.name}}  {{form.name.errors[0]}}</p>
            <p>密码:{{form.pwd}}  {{form.pwd.errors[0]}} </p>
            <p><input type="submit" value="提交"  ></p>
        </form>
    </body>
    </html>

    32、wtforms的注册实例,数据库实时更新

    出现数据库未实时更新的原因是如下,类的静态字段在实例化时只会导入一次,之后不作处理

    若想实时更新,需要将静态字段放在__init__里,每次实例化的时候都导入一次

    class Foo(object):
    
        country = helper.fetch_all('select id,name from tb1',[],type=None)
    
        def __init__(self):
            self.name = '东北'
    
    
    print(Foo.country)
    obj = Foo()
    obj = Foo()
    obj = Foo()
    obj = Foo()
    obj = Foo()
    obj = Foo()

    views.py

    class RegisterForm(Form):
        name = simple.StringField(
            label='用户名',
            validators=[
                validators.DataRequired()
            ],
            widget=widgets.TextInput(),
            render_kw={'class': 'form-control'},
            default='alex'
        )
    
        pwd = simple.PasswordField(
            label='密码',
            validators=[
                validators.DataRequired(message='密码不能为空.')
            ],
            widget=widgets.PasswordInput(),
            render_kw={'class': 'form-control'}
        )
    
        pwd_confirm = simple.PasswordField(
            label='重复密码',
            validators=[
                validators.DataRequired(message='重复密码不能为空.'),
                validators.EqualTo('pwd', message="两次密码输入不一致")
            ],
            widget=widgets.PasswordInput(),
            render_kw={'class': 'form-control'}
        )
    
        email = html5.EmailField(
            label='邮箱',
            validators=[
                validators.DataRequired(message='邮箱不能为空.'),
                validators.Email(message='邮箱格式错误')
            ],
            widget=widgets.TextInput(input_type='email'),
            render_kw={'class': 'form-control'}
        )
    
        gender = core.RadioField(
            label='性别',
            choices=(
                (1, ''),
                (2, ''),
            ),
            coerce=int # int("1")
        )
        city = core.SelectField(
            label='城市',
            choices=(
                ('bj', '北京'),
                ('sh', '上海'),
            )
        )
    
        hobby = core.SelectMultipleField(
            label='爱好',
            choices=(
                (1, '篮球'),
                (2, '足球'),
            ),
            coerce=int
        )
    
        favor = core.SelectMultipleField(
            label='喜好',
            choices=(
                (1, '篮球'),
                (2, '足球'),
            ),
            widget=widgets.ListWidget(prefix_label=False),
            option_widget=widgets.CheckboxInput(),
            coerce=int,
            default=[1, ]
        )
    
    
    
    @app.route('/register', methods=['GET', 'POST'])
    def register():
        if request.method == 'GET':
            form = RegisterForm()
            return render_template('register.html', form=form)
    
        form = RegisterForm(formdata=request.form)
        if form.validate():
            print(form.data)
            return redirect('https://www.luffycity.com/home')
    
        return render_template('register.html', form=form)
    
    import helper
    class UserForm(Form):
        city = core.SelectField(
            label='城市',
            choices=(),
            coerce=int
        )
        name = simple.StringField(label='姓名')
    
        def __init__(self,*args,**kwargs):
            super(UserForm,self).__init__(*args,**kwargs)                   #数据库实时更新
    
            self.city.choices=helper.fetch_all('select id,name from tb1',[],type=None)
    
    
    @app.route('/user')
    def user():
        if request.method == "GET":
            #form = UserForm(data={'name':'alex','city':3})
            form = UserForm()
            return render_template('user.html',form=form)
    
    
    if __name__ == '__main__':
        app.run()

    register.html

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        <form method="post" novalidate>
    
            {% for field in form %}
            <p>{{field.label}}: {{field}}   {{field.errors[0]}}</p>
            {% endfor %}
    
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    33、review

    第一部分:Flask
            1. flask和django比较?
            
            2. wsgi?
                
            3. flask上下文理解?
                两类:
                    请求上下文管理
                    应用上下文管理
                流程:
                    请求到来:
                        将请求和session相关封装到ctx = RequestContext对象中。
                        将app和g封装到app_ctx = AppContext对象中。
                        再通过LocalStack对象将ctx、app_ctx封装到Local对象中。
                        
                        问题:
                            Local是什么?作用?
                            LocalStack是什么?作用?
                    获取数据
                        通过LocalProxy对象+偏函数,调用LocalStack去Local中获取响应ctx、app_ctx中封装的值。
                        
                        问题:
                            为什么要把 ctx=request/session    app_ctx = app/g    ?
                            答:因为离线脚本需要使用app_ctx。
                    请求结束:
                        调用LocalStack的pop方法,将ctx和app_ctx移除。
                            
            4. threading.local 
            
            5. 偏函数 
            
            6. 单例模式
            
            7. 问题: 
                before_request的执行时机(源码实现),在local之后,因为local需要request

    34、review  - database  Mysql

    1. 数据库引擎
            
            2. 数据库授权
            
            3. 表结构设计:代码统计(教育机构,班级表结构设计)
                
            4. SQL语句
               https://www.cnblogs.com/wupeiqi/articles/5729934.html
                
            5. 了解:https://www.cnblogs.com/wupeiqi/articles/5713323.html
                - 视图
                - 存储过程
                - 触发器
                - 函数
                    select max(id) from tb group by xid;
            
            6. 索引 
                索引作用:加速查找+约束。
                索引种类:
                    - 主键索引:加速查找、不重复、非空
                    - 唯一索引:加速查找、不重复
                    - 普通索引:加速查找
                    - 联合索引:加速查找
                    - 联合唯一索引:加速查找、不重复
                    PS:联合索引遵循最左前缀原则。
                    
                        id   name   pwd   email 
                        
                        select * from tb where name='x'
                        select * from tb where name='x' and pwd='123'
                        select * from tb where name='x' and pwd='123' and email='xs'
                        
                    
                名词:
                    - 覆盖索引:在索引文件中就可以把想要的数据得到。
                        select name from tb1;
                    - 索引合并:使用多个单列索引去查找数据。
                    

     35、类的知识点储备

      1、对象可以被for循环

        - form对象为什么可以被for循环?
                  答:变为可迭代对象。
                        class Foo(object):
    
                        # def __iter__(self):
                        #     return iter([11,22,33])     #iter()为生成器
    
                        def __iter__(self):
                            yield 1
                            yield 2          #生成器也是迭代器的一种
                            yield 3
    
                    obj = Foo()
    
    
                    for item in obj:
                        print(item)

      2、 new方法的返回值决定对象到底是什么?

              class Bar(object):
                        pass
    
                    class Foo(object):
    
                        def __new__(cls, *args, **kwargs):
                            # return super(Foo,cls).__new__(cls,*args, **kwargs)
                            return Bar()
                    obj = Foo()
                    print(obj)

      3、 metaclass

    # 1. 类创建的两种方式
    
    # class Foo(object):
    #     a1 = 123
    #     def func(self):
    #         return 666
    
    # Foo = type("Foo",(object,),{'a1':123,'func':lambda self:666})
    
    # 2. 自定义type
    
    # class MyType(type):
    #     pass
    #
    # class Foo(object,metaclass=MyType):
    #     a1 = 123
    #     def func(self):
    #         return 666
    #
    # Foo = MyType("Foo",(object,),{'a1':123,'func':lambda self:666})
    
    # 注意:metaclass作用是指定当前类由谁来创建。

    分析

              - 创建类时,先执行type的__init__。
                    - 类的实例化时,执行type的__call__,__call__方法的的返回值就是实例化的对象。
                        __call__内部调用:
                            - 类.__new__,创建对象
                            - 类.__init__,对象的初始化
                    
                    class MyType(type):
                        def __init__(self,*args,**kwargs):
                            super(MyType,self).__init__(*args,**kwargs)
    
                        def __call__(cls, *args, **kwargs):
                            obj = cls.__new__(cls)
    
                            cls.__init__(obj,*args, **kwargs)
    
                            return obj
    
                    class Foo(object,metaclass=MyType):
                        a1 = 123
                        def __init__(self):
                            pass
    
                        def __new__(cls, *args, **kwargs):
                            return object.__new__(cls)
    
                        def func(self):
                            return 666
    
                    # Foo是类
                    # Foo是MyType的一个对象
    
                    obj = Foo()

     36、SQLAlchemy 

        SQLAlchemy,ORM框架。
            作用:帮助我们使用类和对象快速实现数据库操作。
            
            数据库:
                - 原生:
                    - MySQLdb:py2
                    - pymysql:py2/py3 
                    http://www.cnblogs.com/wupeiqi/articles/5095821.html
    
                - ORM框架
                    - SQLAlchemy

    使用

    SQLAlchemy使用:
                参考:https://www.cnblogs.com/wupeiqi/articles/8259356.html
                
            
                1. 单表操作
                    表:
                        from sqlalchemy.ext.declarative import declarative_base
                        from sqlalchemy import Column
                        from sqlalchemy import Integer,String,Text,Date,DateTime
                        from sqlalchemy import create_engine
    
    
                        Base = declarative_base()
    
                        class Users(Base):
                            __tablename__ = 'users'
    
                            id = Column(Integer, primary_key=True)
                            name = Column(String(32), index=True, nullable=False)
    
    
                        def create_all():
                            engine = create_engine(
                                "mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
                                max_overflow=0,  # 超过连接池大小外最多创建的连接
                                pool_size=5,  # 连接池大小
                                pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
                                pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
                            )
    
                            Base.metadata.create_all(engine)
    
                        def drop_all():
                            engine = create_engine(
                                "mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
                                max_overflow=0,  # 超过连接池大小外最多创建的连接
                                pool_size=5,  # 连接池大小
                                pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
                                pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
                            )
                            Base.metadata.drop_all(engine)
    
                        if __name__ == '__main__':
                            create_all()
                    
                    行:
                        示例:
                            from sqlalchemy.orm import sessionmaker
                            from sqlalchemy import create_engine
                            from models import Users
    
                            engine = create_engine(
                                    "mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
                                    max_overflow=0,  # 超过连接池大小外最多创建的连接
                                    pool_size=5,  # 连接池大小
                                    pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
                                    pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
                                )
                            SessionFactory = sessionmaker(bind=engine)
    
                            # 根据Users类对users表进行增删改查
                            session = SessionFactory()
    
                            # 1. 增加
                            # obj = Users(name='alex')
                            # session.add(obj)
                            # session.commit()
    
                            # session.add_all([
                            #         Users(name='小东北'),
                            #         Users(name='龙泰')
                            # ])
                            # session.commit()
    
                            # 2. 查
                            # result = session.query(Users).all()
                            # for row in result:
                            #         print(row.id,row.name)
    
                            # result = session.query(Users).filter(Users.id >= 2)
                            # for row in result:
                            #         print(row.id,row.name)
    
                            # result = session.query(Users).filter(Users.id >= 2).first()
                            # print(result)
    
                            # 3.删
                            # session.query(Users).filter(Users.id >= 2).delete()
                            # session.commit()
    
                            # 4.改
                            # session.query(Users).filter(Users.id == 4).update({Users.name:'东北'})
                            # session.query(Users).filter(Users.id == 4).update({'name':'小东北'})
                            # session.query(Users).filter(Users.id == 4).update({'name':Users.name+"DSB"},synchronize_session=False)
                            # session.commit()
    
    
    
                            session.close()

    常用

    # ############################## 其他常用 ###############################
    # 1. 指定列
    # select id,name as cname from users;
    # result = session.query(Users.id,Users.name.label('cname')).all()
    # for item in result:
    #         print(item[0],item.id,item.cname)
    # 2. 默认条件and
    # session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
    # 3. between
    # session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
    # 4. in
    # session.query(Users).filter(Users.id.in_([1,3,4])).all()
    # session.query(Users).filter(~Users.id.in_([1,3,4])).all()
    # 5. 子查询
    # session.query(Users).filter(Users.id.in_(session.query(Users.id).filter(Users.name=='eric'))).all()
    # 6. and 和 or
    # from sqlalchemy import and_, or_
    # session.query(Users).filter(Users.id > 3, Users.name == 'eric').all()
    # session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
    # session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
    # session.query(Users).filter(
    #     or_(
    #         Users.id < 2,
    #         and_(Users.name == 'eric', Users.id > 3),
    #         Users.extra != ""
    #     )).all()
    
    # 7. filter_by
    # session.query(Users).filter_by(name='alex').all()
    
    # 8. 通配符
    # ret = session.query(Users).filter(Users.name.like('e%')).all()
    # ret = session.query(Users).filter(~Users.name.like('e%')).all()
    
    # 9. 切片
    # result = session.query(Users)[1:2]
    
    # 10.排序
    # ret = session.query(Users).order_by(Users.name.desc()).all()
    # ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()
    
    # 11. group by
    from sqlalchemy.sql import func
    
    # ret = session.query(
    #         Users.depart_id,
    #         func.count(Users.id),
    # ).group_by(Users.depart_id).all()
    # for item in ret:
    #         print(item)
    #
    # from sqlalchemy.sql import func
    #
    # ret = session.query(
    #         Users.depart_id,
    #         func.count(Users.id),
    # ).group_by(Users.depart_id).having(func.count(Users.id) >= 2).all()
    # for item in ret:
    #         print(item)
    
    # 12.union 和 union all
    """
    select id,name from users
    UNION
    select id,name from users;
    """
    # q1 = session.query(Users.name).filter(Users.id > 2)
    # q2 = session.query(Favor.caption).filter(Favor.nid < 2)
    # ret = q1.union(q2).all()
    #
    # q1 = session.query(Users.name).filter(Users.id > 2)
    # q2 = session.query(Favor.caption).filter(Favor.nid < 2)
    # ret = q1.union_all(q2).all()

     37、SQLAlchemy 

  • 相关阅读:
    构建之法 阅读笔记04
    团队项目-个人博客6.6
    个人总结
    第十六周学习进度条
    第十五周学习进度条
    构建之法阅读笔记07
    大道至简阅读笔记03
    大道至简阅读笔记02
    大道至简阅读笔记01
    第十四周学习进度条
  • 原文地址:https://www.cnblogs.com/di2wu/p/10205468.html
Copyright © 2011-2022 走看看