zoukankan      html  css  js  c++  java
  • flask综合整理1

    前言:

    框架的对比

           Django:1个重武器,包含了web开发中常用的功能、组件的框架;(ORM、Session、Form、Admin、分页、中间件、信号、缓存、ContenType....);

      Tornado:2大特性就是异步非阻塞、原生支持WebSocket协议;

      Flask:封装功能不及Django完善,性能不及Tornado,但是Flask的第三方开源组件比丰富;http://flask.pocoo.org/extensions/

      Bottle:比较简单;

    总结:

      不论优劣,不同的工具而已;

      小型web应用设计的功能点不多使用Flask;

      大型web应用设计的功能点比较多使用的组件也会比较多,使用Django(自带功能多不用去找插件);

      如果追求性能可以考虑Tornado;

    Flask的socket是基于Werkzeug 实现的,模板语言依赖jinja2模板,在使用Flask之前需要安装一下;

    pip3 install flask #安装flask

    Flask简单使用

    from flask import Flask,response
    
    app=Flask(__name__) #创建1个Flask实例
    
    @app.route('/')      #路由系统生成 视图对应url,
    def first_flask():    #视图函数
        return 'Hello World'  #response
    
    
    if __name__ == '__main__':
        app.run()              #启动socket

    一、flask的配置文件

    app=Flask(__name__,template_folder='templates',static_url_path='/static/',static_path='/lizhiqiang')
    #模板路径: template_folder='templates'
    
    #静态文件路径:static_url_path='/static/'
    
    #静态文件引入别名:static_path='/zhanggen'
    
    #设置为调试环境:app.debug=True (代码修改自动更新)
    
    #设置json编码格式 如果为False 就不使用ascii编码:app.config['JSON_AS_ASCII']=False 
    
    #设置响应头信息Content-Type   app.config['JSONIFY_MIMETYPE'] ="application/json;charset=utf-8"  (注意 ;charset=utf-8)

    二、路由系统

    1.动态路由(url传参)

    @app.route('/user/<name>')

    from flask import Flask
    
    app=Flask(__name__)
    
    @app.route('/<name>')  #设置url传参数 http://127.0.0.1:5000/zhanggen
    def first_flask(name):  #视图必须有对应接收参数
        print(name)
        return 'Hello World'  #response
    
    
    if __name__ == '__main__':
        app.run()
    
    接收字符串类型参数

    @app.route('/post/<int:age>')

    #接收整型数字参数
    app=Flask(__name__)
    @app.route('/<int:age>/')  #设置url传参数 http://127.0.0.1:5000/18/
    def first_flask(age):  #视图必须有对应接收参数
        print(age)
        return 'Hello World'  #response
    
    if __name__ == '__main__':
        app.run()
    
    接收整型数字参数

    2、指定允许的请求方法

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

    # 指定允许的请求方法
    app=Flask(__name__)
    @app.route('/<path:url>/',methods=['get']) #只允许get请求
    def first_flask(url):
        print(url)
        return 'Hello World'  #response
    
    if __name__ == '__main__':
        app.run()
    
    指定允许的请求方法

    3、通过别名反向生成url

    #反向生成url
    from flask import Flask,url_for
    app=Flask(__name__)
    @app.route('/<path:url>',endpoint='name1')
    def first_flask(url):
        print(url_for('name1',url=url)) #如果设置了url参数,url_for(别名,加参数)
        return 'Hello World'
    
    if __name__ == '__main__':
        app.run()
    
    url_for()反向生成url

    4、扩展路由功能:正则匹配url

    from flask import Flask, views, url_for
                from werkzeug.routing import BaseConverter
    
                app = Flask(import_name=__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
    
                # 添加到flask中
                app.url_map.converters['regex'] = RegexConverter
    
    
                @app.route('/index/<regex("d+"):nid>')
                def index(nid):
                    print(url_for('index', nid='888'))
                    return 'Index'
    
    
                if __name__ == '__main__':
                    app.run()
    View Code

    三、视图

    1、给Flask视图函数加装饰器

    注意如果要给视图函数加装饰器增加新功能,一点要加在路由装饰器下面,才会被路由装饰器装饰,才能生生成url关系;

    #给Flask视图加装饰器
    #1、定义1个装饰器
    
    def auth(func):
        print('我在上面')
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    
    
    app=Flask(__name__)
    
    @app.route('/',methods=['GET'])
    @auth #注意如果要给视图函数加装饰器,一点要加在路由装饰器下面,才会被路由装饰器装饰
    def first_flask():
        print('ffff')
        return 'Hello World'
    
    if __name__ == '__main__':
        app.run()
    #给Flask视图加装饰器
    #1、定义1个装饰器
    
    def auth(func):
        print('我在上面')
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    
    
    app=Flask(__name__)
    
    @app.route('/',methods=['GET'])
    @auth #注意如果要给视图函数加装饰器,一点要加在路由装饰器下面,才会被路由装饰器装饰
    def first_flask():
        print('ffff')
        return 'Hello World'
    
    if __name__ == '__main__':
        app.run()

    2、request和response

     a.请求相关信息

    request.method: 获取请求方法

    request.json

    request.json.get("json_key"):获取json数据 **较常用      

    request.argsget('name') :获取get请求参数   

    request.form.get('name') :获取POST请求参数

    request.form.getlist('name_list'):获取POST请求参数列表(多个)

    request.values.get('age') :获取GET和POST请求携带的所有参数(GET/POST通用)

    request.cookies.get('name'):获取cookies信息

    request.headers.get('Host'):获取请求头相关信息

    request.path:获取用户访问的url地址,例如(/,/login/,/ index/);

    request.full_path:获取用户访问的完整url地址+参数 例如(/login/?age=18)

    request.script_root: 抱歉,暂未理解其含义;

    request.url:获取访问url地址,例如http://127.0.0.1:5000/?age=18;

    request.base_url:获取访问url地址,例如 http://127.0.0.1:5000/;

    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))  直接保存

     

     b、响应相关信息

    return "字符串" :响应字符串

    return render_template('html模板路径',**{}):响应模板

    return redirect('/index.html'):跳转页面

    3 、Flask之CBV视图

    #CBV视图
    from flask import Flask,url_for,views
    #-----------------------------------------------------
    app=Flask(__name__)               #装饰器
    
    def auth(func):
        print('我在上面')
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    #--------------------------------------------------------
    class IndexView(views.MethodView):  #CBV视图
        methods=['GET']                #允许的http请求方法(改CBV只允许GET方法)
        decorators = [auth,]            #每次请求过来都加auth装饰器
    
        def get(self):
            return 'Index.GET'
        def post(self):
            return 'Index.POST'
    
    app.add_url_rule('/index/',view_func=IndexView.as_view(name='name1')) #(name='name1'反向生成url别名
    
    
    if __name__ == '__main__':
        app.run()

    五、模板语言

    Flask使用的是Jinja2模板,所以其语法和Django无差别(Django的模板语言参考Jinja2)

    1.引用静态文件

    方式1:别名引入

    <link rel="stylesheet" href="/zhanggen/commons.css">

    方式2:url_for()方法引入

    <link rel="stylesheet" href="{{  url_for('static',filename='commons.css')  }}">

    2.模板语言引用上下文对象

    变量

    <h1>{{user_list}}</h1> <!--变量 -->
    <h1>{{user_list}}</h1> <!--变量 -->

    循环、索引取值

    <ul>
    {% for user in user_list %} <!--循环 -->
    <li>{{user}}</li>
    {% endfor %}

    {{user_list.0}} <!-- 索引取值-->

    </ul>

    复制代码
    <ul>
    {% for user in user_list %}   <!--循环 -->
        <li>{{user}}</li>
    {% endfor %}
    
    {{user_list.0}}             <!-- 索引取值-->
    
    </ul>
    复制代码

    Flask的Jinjia2可以通过Context 把视图中的函数传递把模板语言中执行,这就是Django中的simple_tag和simple_fifter;

    simple_tag(只能传2个参数,支持for、if)

    @app.template_global()   #simple_tag
    def foo(arg):
        return '<input type="text">'
    @app.template_global()   #simple_tag
    def foo(arg):
        return '<input type="text">'
    <h1>{{foo(1)|safe}}</h1>                   <!--Flask的模板语言支持simple_tag-->
    <h1>{{foo(1)|safe}}</h1>                   <!--Flask的模板语言支持simple_tag-->

    3.wtform(flask表单验证插件)

    3.1. 安装

    pip install wtforms  #安装wtfroms插件

    3.2登录注册

    from flask import Flask,render_template,request
    from wtforms import Form
    from wtforms.fields import simple,core
    from wtforms import validators
    
    app = Flask(__name__)
    
    #登录
    class LoginFrom(Form):
        username = simple.StringField(
            label='用户名',
            validators=[
                validators.DataRequired(message='用户名不能是空'),
                validators.Length(min=3,max=16,message='用户名必须大于%(min)d且小于%(max)d')
    
            ],
        )
        password = simple.PasswordField(
            label='密码',
            validators=[
                validators.DataRequired(message='密码不能是空'),
                validators.Length(min=3, max=16, message='密码必须大于%(min)d且小于%(max)d')
    
            ],
        )
    
    @app.route('/',methods=['GET','POST'])
    def login():
        if request.method == 'GET':
            fm = LoginFrom()
            return render_template('login.html',wtf=fm)
        else:
            form = LoginFrom(formdata=request.form)
            if form.validate():
                return "ok"
    
            else:
                return  render_template('login.html',wtf=form)
    
    
    #注册
    class RegForm(Form):
        username=simple.StringField(
            label='用户名',
            validators=[
                validators.DataRequired(message='用户名不能为空'),
                validators.Length(min=3,max=16,message='用户名必须大于%(min)d且小于%(max)d'),
            ]
        )
        password = simple.PasswordField(
            label='密码',
            validators=[
                validators.DataRequired(message='密码不能是空'),
                validators.Length(min=3, max=16, message='密码必须大于%(min)d且小于%(max)d'),
                validators.Email(message='密码必须符合邮箱规则')
            ],
        )
        repassword= simple.PasswordField(
            label='确认密码',
            validators=[validators.EqualTo(fieldname='password',message='密码不一致')]
        )
        gender=core.SelectMultipleField(
            label="爱好",
            validators=[validators.Length(min=2, max=4, message="癖好有问题")],
            coerce=int,
            choices=(
                (1, "fengjie"),
                (2, "luoyufeng"),
                (3, "lixueqin"),
                (4, "wuyifan"),
                (5, "panta")
            ),
            default=(1, 3, 5)
        )
    
    @app.route('/reg',methods=["GET","POST"])
    def reg():
        if request.method == "GET":
            fm = LoginFrom()
            return  render_template("reg.html",rf=fm)
        else:
            form = LoginFrom(request.data)
            if form.validate():
                return form.data.get("password")
            else:
                return render_template("reg.html", rf=form)
    
    if __name__ == '__main__':
        app.run(debug=True)

    html

    #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 action="" method="post" novalidate>
      {{ wtf.username.label }}
      {{ wtf.username }}
      <p><h1>{{wtf.username.errors.0}}</h1></p>
      <p>
          {{ wtf.password.label }}
      {{ wtf.password }}
      </p>
      <p><h1>{{wtf.password.errors.0}}</h1></p>
      <input type="submit" value="登录">
    </form>
    </body>
    </html>
    
    
    
    #reg.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 action="" method="post" novalidate>
      {% for field in rf %}
        <p>{{ field.label }}{{ field }}{{ field.errors.0 }}</p>
      {% endfor %}
      <input type="submit" value="注册">
    </form>
    </body>
    </html>

    3.33.2.wtforms源码 猜想....

    源码给你们一个链接吧,头疼

    https://www.cnblogs.com/sss4/p/8097653.html

    未完待续。。。

  • 相关阅读:
    推荐系统入门笔记2--信息检索 Lucene
    Mybatis多个参数,其中有hashMap的写法
    Java中fastjson的toJSONString结果为空{}
    Linux中less命令出现ESC乱码
    关于博客
    【Uni-App】关于获取手机系统信息的项目实践
    mysql 服务列表找不到
    服务网格与Istio
    ARM架构服务器如何运行EasyNVR软件提示无法识别二进制文件排查及解决
    关于EasyNVR拉流摄像头的视频流存在视频流锁定机制的问题说明
  • 原文地址:https://www.cnblogs.com/lzqrkn/p/10274480.html
Copyright © 2011-2022 走看看