zoukankan      html  css  js  c++  java
  • flask不得不知的基础

    python与flask不得不说的小秘密

    常识引入

    1. 什么是装饰器?

      在不改变源码的前提下,对函数之前前后进行功能定制.
      
      开放封闭原则:不改变函数内部代码,在函数外部进行修改.
      
    2. 基本写法

      import functools
      
      def wrapper(func):
          @functools.wraps(func)
          def inner(*args, **kwargs):
              return func(*args, **kwargs)
      
          return inner
       
      @wrapper
      def index(xx):
          pass
      
      @wrapper
      def order(xx):
          pass
      
      print(index.__name__) # "inner"
      print(order.__name__) # "inner"
      
    3. 函数应用多个装饰器

      import functools
      
      def wrapper1(func):
          @functools.wraps(func)
          def inner(*args, **kwargs):
              print('w1')
              return func(*args, **kwargs)
      
          return inner
      
      def wrapper2(func):
          @functools.wraps(func)
          def inner(*args, **kwargs):
              print('w2')
              return func(*args, **kwargs)
      
          return inner
      
      @wrapper1
      @wrapper2
      def index():
          print('index')
      
      index()
      

    flask和django不得不公布的绯闻

    1.flask和django的区别?

    flask,是一个轻量级的框架,内置了:路由/视图/模板(jinja2)/cookie/session/中间件.  可扩展强,第三方组件非常多,例如:wtforms/flask-session/flask-sqlalchemy.
    
    django,是一个重武器,django内置了很多功能方便我们使用,例如:admin/orm/模板/form/modelform/session/cookie/中间件/路由/缓存/信号/数据库的读写分离/分页... 
    
    flask,短小精悍可扩展强. 
    django,大而全重武器.
    
    • django好还是flask好?

      小程序,flask比较好.
      中大型,django比较好.
      

    2.快速入门

    pip3 install flask
    

    2.1 werkzurg

    werkzurg是一个wsgi,本质上提供了socket服务端,用于接收用户请求.

    django和flask一样,它们内部都没有实现socket服务端,需要依赖wsgi.

    • django, wsgiref
    • flask, werkzurg

    2.1.1 wsgiref实现一个网站

    from wsgiref.simple_server import make_server
    
    class WSGIHandler(object):
    
        def __call__(self,environ, start_response):
            start_response('200 OK', [('Content-Type', 'text/html')])
            return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]
    
    
    if __name__ == '__main__':
        obj = WSGIHandler()
        httpd = make_server('127.0.0.1', 8000, obj)
        httpd.serve_forever()
    

    2.1.2 werkzeug实现一个网站

    from werkzeug.wrappers import Response
    from werkzeug.serving import run_simple
    
    class Flask(object):
        def __call__(self,environ, start_response):
            return Response('Hello World!')(environ, start_response)
    
    
    if __name__ == '__main__':
        app = Flask()
        run_simple('127.0.0.1', 5000, app)
    

    2.2 flask程序

    from flask import Flask
    
    # 实例化了一个Flask对象
    app = Flask(__name__)
    
    
    # 添加路由关系
    @app.route('/index')
    def index():
        return '你好'
    
    
    if __name__ == '__main__':
        # 启动服务端
        app.run()
    

    3.flask用户登陆实例

    关于返回值

    ```python
    from flask import Flask,render_template,request,redirect
    
    app = Flask(__name__)
    
    @app.route('/login',methods=['GET','POST'])
    def login():
    	return "xxx"
    	return render_template('模板文件',参数)
    	return redirect(...)
    	return jsonify({"k1":123})
    if __name__ == '__main__':
        app.run()
    ```
    

    关于模板

    ```
    默认放在根目录的tempaltes文件夹下
    
    ```
    

    关于用户请求

    ```
    request.method
    request.form  # POST请求传来的数据
    request.args  # GET url中的参数信息
    
    ```
    

    session

    ```
    加密的形式放在用户浏览器的cookie中. 
    
    # 登录操作
    from flask import request, session
    app.secret_key = 'sasashasalks'
    
    @app.route('/login', methods=['POST', 'GET'])
    def login():
        if request.method == 'POST':
            if request.form['user'] == 'admin':
                session['user'] = request.form['user']
                return 'Hello World!'
            else:
                return 'No such user!'
        if 'user' in session:
            return 'Hello %s!' % session['user']
        else:
            title = request.args.get('title', 'Default')
            return render_template('login.html', title=title)
    ```
    

    在flask视图中添加装饰器

    -   位置route的下面
    -   记得加functools.wraps(...) , 保留函数的元信息.
    

    特殊装饰器:before和after request装饰器

    ```
    # 主要的是,执行顺序:before_request在视图函数执行前顺序执行,after_request在函数执行后,逆序执行(flask内部会先对after_request列表进行逆序再执行)
    
    from flask import Flask,render_template,request,redirect,jsonify,url_for,session
    import functools
    app = Flask(__name__)
    
    app.secret_key = "29ualknd872iuknsdgf"
    
    @app.before_request
    def f1():
        print('f1')
    
    @app.before_request
    def f11():
        print('f11')
    
    @app.after_request
    def f2(response):
        print('f2')
        return response
    
    @app.after_request
    def f22(response):
        print('f22')
        return response
    
    @app.route('/login')
    def login():
        print('login')
        return 'Login'
    
    @app.route('/index')
    def index():
        print('index')
        return 'index'
    
    if __name__ == '__main__':
        app.run()
        
    # 显示顺序:
    f1  f11  f22  f2  f1  f11  f22  f2
    ```
    

    4. 路由中的重要参数

    # 主要的
    endpoint=""     默认是函数名, 可以在app.route()的关键字参数中定义,默认是对应的函数名,当登陆验证使用装饰器时,应注意装饰器的inner函数名会影响路由的解析,所以再装饰其中要使用funcktools.wraps(...)来保留原函数信息
    url_for("")     反向地址, 通过视图函数名, 或endpoint解析对应的URL
    methods=[]      该视图函数能处理的请求方式, 默认是GET, 当重新定义了methods, 那么默认的GET也会被覆盖
    
    # 一般的
    defaults={}     给视图函数传递参数, 可以作为默认参数, 传了就必须的接
    strict_slashes=Bool     严格的使用"/", URL中没有"/", 访问时也不能有, URL中有"/", 你访问时没有, 会通过301进行永久重定向
    redirect_to=""      永久重定向
    
    # 动态路由参数
    '/shopping/<int:year>/<string:month>'   路由中使用参数, 并可以转换参数的数据类型, 切记数字可以转字符串, 字符串不能转数字
    
  • 相关阅读:
    搜索算法总结
    浅谈cocosd之autorelease etain elease的理解
    lua和C++的交互(1)
    Unity相对于Cocos2d-x的比较
    Lua弱表Weak table
    socket编程学习step2
    ppt述职摘要
    LuaJavaBridge
    鱼书学习小结(一)
    网络协议HTTP TCP/UDP 浏览器缓存 Restful(十)
  • 原文地址:https://www.cnblogs.com/jjzz1234/p/12019539.html
Copyright © 2011-2022 走看看