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 

  • 相关阅读:
    sqlhelper使用指南
    大三学长带我学习JAVA。作业1. 第1讲.Java.SE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行 大三学长带我学习JAVA。作业1.
    pku1201 Intervals
    hdu 1364 king
    pku 3268 Silver Cow Party
    pku 3169 Layout
    hdu 2680 Choose the best route
    hdu 2983
    pku 1716 Integer Intervals
    pku 2387 Til the Cows Come Home
  • 原文地址:https://www.cnblogs.com/di2wu/p/10205468.html
Copyright © 2011-2022 走看看