flask介绍

安装flask

pip3 install flask 

短小精悍、可扩展强 的一个Web框架。

牛逼点:上下文管理机制

依赖wsgi:

   werkzeug(相当于Django的wsgi):只要安装flask,就有werkzeug了。

底层实现一:
from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple
请求进来---------------------

def run(environ,start_response):

    return [b"asdfasdf"] 返回

if __name__ == '__main__':
监听4000端口

    run_simple('localhost', 4000, run)

底层实现二:
 
from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
response对象也可以
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

备注:

flask源码入口

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()
class Foo(object):

    def __init__(self):
        print('sdfsdf')

    def __call__(self, *args, **kwargs):
        print('call')
        
类+()执行__init__方法
obj = Foo()

类+()执行__call__方法
obj()

简单使用:

from flask import Flask
步骤1实例化flask---------------
app = Flask(__name__)


步骤2视图函数------------------
@app.route('/index')
def index():
    return "Hello World"

    
步骤3运行---------------------------    
if __name__ == '__main__':
    app.run()

给你一个路径 ,获取类并获取其中的大写的静态字段

给你一个路径 “settings.Foo”,可以找到类并获取去其中的大写的静态字段。

settings.py文件
    class Foo:
        DEBUG = True
        TEST = True

xx.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))        

flask系统组件:

1. 配置文件

app.py:
        
        app.config.from_object("settings.DevelopmentConfig")
        
        
        settings.py:
            class Config(object):
                DEBUG = False
                TESTING = False
                DATABASE_URI = 'sqlite://:memory:'


            class ProductionConfig(Config):
                DATABASE_URI = 'mysql://user@localhost/foo'

            开发环境
            class DevelopmentConfig(Config):
                DEBUG = True

            测试环境
            class TestingConfig(Config):
                TESTING = True

2. 路由系统

自定义装饰器放下面

  • @app.route('/user/<username>'):不加类型是字符串
  • @app.route('/post/<int:post_id>')整型
  • @app.route('/post/<float:post_id>')小数
  • @app.route('/post/<path:path>')路径
  • @app.route('/login', methods=['GET', 'POST'])方法
  • 自定义正则
1:无参数的反向解析:--------------------------------------------
  导入
url_for,指定endpoint名字,
    不指定:默认是函数名
    重名:项目无法启动

from
flask import Flask,url_for app=Flask(__name__) @app.route('/indexaaaaa',methods=['GET','POST'],endpoint='n1') def index(): print(url_for('n1')) return 'Index' if __name__ == '__main__': app.run()

2:有参数的反向解析:----------------------------------------------------

from flask import Flask,url_for

app=Flask(__name__)

@app.route('/index/<int:nid>',methods=['GET','POST'],endpoint='n1')
def index(nid):
print(url_for('n1',nid=666))反向解析有参解析
return 'Index'

if __name__ == '__main__':
app.run()
 
from werkzeug.routing import BaseConverter
from flask import Flask,url_for

app = Flask(__name__)

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()
自定义正则表达式

3. 视图

FBV(基于函数的)

CBV(基于类的)

第一步导入views
from flask import Flask,views
第六步添加配置信息(不写则没有注释文件)
import functools app = Flask(__name__) def wrapper(func):
第七步应用配置信息类 @functools.wraps(func):切记加上,否则被装饰的函数都成inner了。
def inner(*args,**kwargs): return func(*args,**kwargs) return inner 第二步定制一个类,继承views.MethodView类 class UserView(views.MethodView): methods = ['GET'] # 给CBV加装饰器 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('uuu')) if __name__ == '__main__':
第四步执行函数 app.run()

 

4. 请求相关

from flask import Flask,render_template,request,redirect,url_forapp = Flask(__name__)

@app.route('/login',methods=['GET','POST'])
def login():


# 请求相关信息
常用方法
 
 # request.method      # request.form
  # request.cookies
  # request.headers
 
# request.args

# request.values
# request.path
# request.full_path
# request.script_root
# request.url
# request.base_url
# request.url_root
# request.host_url
# request.host

上传文件
# request.files # obj = request.files['the_file_name']
保存路径
# obj.save('/var/www/uploads/' + secure_filename(f.filename))


5. 响应   

from flask import Flask,jsonify

响应体:
  return “asdf”

  return jsonify({'k1':'v1'}):返回json数据
  return render_template('xxx.html')
  return redirect()

定制响应头:
  obj = make_response("asdf")
  obj.headers['xxxxxxx'] = '123'
  obj.set_cookie('key', 'value')
  return obj


6. 模板渲染

- 基本数据类型:
    可以执行python语法,如:dict.get() list['xx'] - 传入函数 - django,自动执行 - flask,不自动执行
---------------------------------------------------------------------------
- 全局定义函数(自定义方法),定义之后模板可以直接进行渲染 py文件定义: @app.template_global()        def sb(a1, a2):        return a1 + a2
       模板使用:{{sb(1,9)}}

------------------------------------------------------------------------------- @app.template_filter()
def db(a1, a2, a3): # {{ 1|db(2,3) }} return a1 + a2 + a3
        模板中使用:{{1|db(2,3)}}
          备注:1第一个参数存入,2第二个参数传入,3第三个参数传入
      

---------------------------------------------------------------------------------
- 模板继承 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")


7. session

加密后放置在用户浏览器的cookie中。
- 流程:
- 请求到来
- 视图函数
- 请求结束

当请求刚到来: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中。



8. 闪现

在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"

      
 

9. 中间件

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


10. 特殊装饰器

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

        给模板用的(在py文件中自定义的方法):
          4. template_global
        
          5. template_filter
        
        6. errorhandler(没找到网页时定制信息,如显示企业广告或失联儿童等)
            @app.errorhandler(404)
            def not_found(arg):
                print(arg)
                return "没找到"

 11.蓝图(flask目录结构)

 文件结构点击下载

 

 

原文地址:https://www.cnblogs.com/wanghuaqiang/p/9174278.html