flask框架简单了解

#python web 框架学习
#####url
    统一资源定位符,指向网络中某个资源的地址
#####HTTP错误码
    状态码 原因短语(用于解释状态码) 说 明
    200     OK                      请求被正常处理
    201     Created                 请求被处理,并创建了一个新资源
    204     No Content              请求处理成功,但无内容返回
    301     Moved Permanently       永久重定向
    302     Found                   临时性重定向
    304     Not Modified            请求的资源未被修改,重定向到缓存的资源
    400     Bad Request             表示请求无效,即请求报文中存在错误
    401     Unauthorized            类似403,表示请求的资源需要获取授权信息,在浏览器中会弹出认证弹窗
    403     Forbidden               表示请求的资源被服务器拒绝访问
    404     Not Found               表示服务器上无法找到请求的资源或 URL 无效
    500     Internal Server Error   服务器内部发生错误
##flask
    flask是python的微框架,其核心简单易于扩展主要有两个依赖
    1、WSGI(web服务网关接口)
    2、Jinja2模板引擎
###安装pipenv来管理虚拟环境
    1.确保安装了pip
        安装方法:
            在https://pypi.org/project/pip/#files中下载后缀名为.tar.gz的压缩包
            解压后进入有setup.py文件的目录下按shift右击选择‘在此处打开命令窗口’
            输入python setup.py install
    2.安装pipenv
        输入pip install pipenv
    3.创建虚拟环境
        创建虚拟环境的原因:
            可以拥有一个独立的python解释器环境,因为不同项目会依赖不同版本的库或python版本,
            避免包和版本的混乱,以便在新环境下复现依赖环境。
        1、输入pipenv install
        此时会创建一个文件夹包含python解释器环境
            默认情况下,Pipenv会统一管理所有虚拟环境。在 Windows系统中,虚拟环境文件夹
        会在C:\Users\Administrator.virtualenvs\目录下创建,而 Linux 或 macOS 会在
        ~/.local/share/virtualenvs/ 目录下创建。如果你想在项目目录内创建虚拟环境文件夹,可以设置
        环境变量 PIPENV_VENV_IN_PROJECT,这时名为.venv的虚拟环境文件夹将在项目根
        目录被创建。
        创建时下行代码为创建虚拟环境目录
        New python executable in E:\workon\blog-OWqOYOKv\Scripts\python.exe
        2、此时可以选择创建的python版本
            pipenv --python 3.6 #生成 python 3.6 版本的虚拟环境
            pipenv  --three #使用python3 版本生成虚拟环境
            pipenv --venv #显示当前虚拟环境所用的解释器位置 
        3、激活
            输入pipenv shell # 显示激活
###安装flask
    在虚拟环境中安装flask
    输入pipenv install flask

###客户端和服务器flask程序交互
    1.用户输入url访问资源
    2.flask接收用户请求并分析url
    3.为url找到相应的处理函数
    4.执行并将生成相应返回浏览器
    5.浏览器接收并解析相应,并将信息显示网页
    在此过程中需要做的是建立处理请求的函数,定义相应的url规则
    需要利用app.route()装饰器来为函数和url之间建立关联,参数为url规则
    此过程被称为注册路由
    而此函数被称为视图函数
###请求报文
    请求报文由请求的方法、URL、协议版本、首部字段(header)和内容实体组成。
####请求方法
    GET     获取资源
    POST    传输数据
    PUT     传输文件
    DELETE  删除文件
    HEAD    获取报文头部
    OPTIONS 询问支持的方法
    报文首部包含了请求的各种信息和设置,例如客户端类型、语言偏好、是否设置缓存等
###request对象
    其封装了客户端的请求报文,可以从中获取到请求报文中的所有数据。
    Werkzeug实现了请求解析和相应封装
    请求request 
    响应response
    获取查询字符串
    from flask import Flask,request
    # 导入Flask,request
    app = Flask(__name__)
    # 设置app名称
    @app.route('/hello')
    def say_hello():
        name = request.args.get('name',Flask) # 获取name的值 使用request对象的get方法获取值(值名,默认值)若获取不到则使用默认值
        return '<h5>hi,%s!<h5>' % name
####设置监听HTTP方法
    @app.route('/hello',methods=['GET','POST'])
    def say_hello():
        return '<h5>hi,Flask!<h5>'
####request请求钩子
    用于对请求进行预处理或后处理
    before_first_request    注册一个函数,在处理第一个请求前运行。
    before_request          注册一个函数,在处理每个请求前运行。
    after_request           注册一个函数,若没有未处理的异常抛出,则在每个请求结束后执行。
    teardown_request        注册一个函数,即使有未处理的异常,也会在每个请求结束后执行,若有异常则将异常对象作为参数传到函数中。
    after_this_request      注册一个函数,在请求结束后运行。
###response对象
    客户端发送请求触发相应视图函数,获取返回值作为响应主体。最后生成的完整响应作为响应报文
    响应报文由协议版本、状态码、原因短语、响应首部、响应主体组成。
####视图函数返回
    视图函数返回最多由3部分组成的元组:响应主体、状态码、首部字段。其中首部字段可以为字典或列表
    普通返回只含主体:
    @app.route('/hello')
    def say_hello():
        ...
        return '<h5>hi,Flask!<h5>'
    指定状态码:
    @app.route('/hello')
    def say_hello():
        ...
        return '<h5>hi,Flask!<h5>',201  
    重定向:
    @app.route('/hello')
    def say_hello():
        ...
        return ' ',302,{'Location','url'}  
    利用redirect函数进行重定向:
    from flask import Flask,redirect
    app = Flask(__name__)
    @app.route('/hello')
    def say_hello():
        return redirect('url')
        # 定位到当前视图函数中使用url_for,需要导入url_for
        # return redirect(url_for('login'))
   #####重定向
        重定向当访问一个页面时,加载完成后的页面url和输入的url发生了变化,这种行为被称为重定向。
   ######返回上一个页面
        1.获取上一个页面的url
            1)使用HTTP的referrer
            在当前页面利用referrer返回
            return redirect(request.referrer)
            防止referrer为空
            return redirect(request.referrer or url_for('url'))                        
            2)使用查询参数   next 在程序内部用相对url full_path
            return '<h1>页面主体信息<h1><a herf="%s">连接信息</a>'%url_for('url',next=request.full_path)
            在当前页面利用next来返回
            return redirect(request.args.get('next'))
            防止next为空
            return redirect(request.args.get('next',url_for('url')))
        因为不同视图执行代码相同所以可以建立redirect_back()函数
        def redirect_back(default='默认的url',**kwargs):
            for target in request.referrer,request.args.get('next'):
                if target:
                    return redirect(target)
            return redirect(url_for(default,**kwargs))
        2.对url进行安全验证
            确保url安全的关键是判断是否属于程序内部需要导入以下模块
            from urllib.parse import urlparse,urljoin
            def is_safe_url(target):
                ref_url = urlparse(request.host_url)
                test_url = urlparse(urljoin(request.host_url,target))
                return test_url.scheme in ('http','https') and ref_url.netloc == test_url.netloc
            
        
   #####abort函数
        输入相应代码返回对应的错误响应
        @app.route('/404')
        def not_found():
            '''
            测试abort函数
            '''
            print('执行完成')
            abort(404)
   #####MIME类型
        是一种用于标示文件类型的机制,与文件扩展名相对应,让客户端区分不同的内容类型,并执行不同操作。
        格式为'类型名/子类型名' 
        设置mime
        @app.route('/mime')
        def set_mime():
            response = make_response('hello,mime')
            response.mimetype = 'text/plain'
            # 或者使用 response.headers['Content-Type']='text/xml;charset=utf-8'
            return response  
   #####jsonify
        jsonify可以传入普通参数也可以传入关键字参数例如字典、元组、列表等
        默认生成200响应
        @app.route('/foo')
        def foo():
            '''
            测试jsonify
            :return: json字符串
            '''
            return jsonify({'name':'lili','age':25})
        
        @app.route('/foo2')
        def foo2():
            '''
            测试jsonify
            :return: json字符串
            '''
            return jsonify(name= 'lili' , age = 25)
        
        # foo和foo2返回数据相同
        
        @app.route('/foo3')
        def foo3():
            '''
            测试jsonify
            :return: json字符串
            '''
            return jsonify(messages='ERROR!'),500  
####cookie
    web服务器为了存储某些数据而保存在浏览器上的小型文本数据
   #####set_cookie
        若在响应中添加cookie则
        1.生成response对象
        response = make_response('响应主体')
        2.设置cookie
        response.set_cookie('cookie_name',cookie的值)
        例如
        @app.route('/set')
        def set_cookie():
            response =make_response('设置cookie')
            response.set_cookie('cookie_name','name')
            return response
   #####get_cookie
        @app.route('/hi')
        def hi():
            '''
            通过cookie来获取需要的值
            :return:返回响应主体
            '''
            name = request.args.get('name')
            if name == None :
                name = request.cookies.get('name','human')
            return '<h5>hi,%s!<h5>'%name
####session
    在flask中session用于加密cookie
    session指用户对话
   #####设置程序秘钥
        session利用秘钥对数据进行签名以及加密。
        1.设置秘钥
        可以利用Flask类的secret_key属性或配置变量SECRET_KEY设置
        app.secret_key = 'secret string'
        安全的做法是将秘钥写入环境变量或保存在.env文件中
        SECRET_KEY = secret string   
        然后在利用os模块的getenv()方法获取
        app.secret_key = os.getenv('SECRET_KEY','secret string')
        session的数据可以通过键值对方式读取或使用get方法
###ajax
    是指在不重载页面的情况下与服务器进行数据交换。
    
###render_template 渲染函数
###模板标签
    {# #} 注释
    {{ }} 变量
    {% %} 
    if 标签
    {% if user.bio %}
    <i>{{ user.bio }}</i>
    {% else %}
        <i>This user has not provided a bio.</i>
    {% endif %}
    for标签
    {% for movie in movies %}
        <li>{{ movie.name }} - {{ movie.year }}</li>
    {% endfor %} 
    {% set navigation %}
        <li><a href='/'>home</a></li>
        <li><a href='/about'>about</a></li>
    {% endset %} 
    
###内置的上下文变量
    config      当前配置对象
    request     当前请求对象
    session     当前会话对象
    g           与请求绑定的全局对象
###模板过滤器filter
    用于对显示数据进行修改和过滤
    可以自定义:
    @app.template_filter()
    def musical(s):
        rerurn s+Markup('&#9835;')
        # Markup用于将其标示为安全字符。
###模板测试去test
    用于测试变量和表达式,返回布尔值
     @app.template_test()
     def baz(n):
     if n == 'baz':
        return True
     return False
###局部模板使用include标签
    使用include来插入局部模板
    局部模板一般命名通常以一个下划线开始
    {% include '_banner.html' %} 
###宏
    将部分模板代码封装到宏中,使用传递的参数构建内容,返回构建的内容
    为了便于管理将宏保存在macros.html 或 _macros.html   
    在创建宏时使用macro标签
    {% macro qux(amout=1) %}
        {% if amout == 1 %}
            i am qux
        {% elif amout > 1 %}
            we are quxs
        {% endif %}
    {% endmacro %}
    使用时
    {% from 'macros.html' import qux %}
    ...
    {{ qux(amout = 5) }}
    with context导入上下文对象
    {% from 'macros.html' import qux with context %}
###模板继承
    extends必须是第一个标签
    {% extends '模板.html' %}
    block标签
    用于替换或追加(使用super()函数可以实现追加而不是直接覆盖)
    {% block 块名 %}
    {{ super() }}
    ...
    {% endblock %}
###模板控制
   ####空白控制
        使用- 减号来控制空白
        {% if amout == 1 -%}
        {# 移除语句后空白 #}
            i am qux
        {% elif amout > 1 -%}
        {# 移除语句后空白 #}
            we are quxs
        {%- endif %}
        {# 移除语句前空白 #}
   ####静态文件加载
        例如
        {{ url_for('static',filename='文件名.后缀名') }}
        添加Favicon
        需要在static文件中建立favicon.ico文件
        <link rel="icon" type="image/x-icon" href="{{ url_for('static',filename='favicon.ico') }}">
        导入bootstarp框架
        <link rel="stylesheet" href="{{ url_for('static',filename='css/bootstarp.min.css') }}">
        <script src="{{ url_for('static',filename='js/jquery.slim.min.js') }}"></script>
        <script src="{{ url_for('static',filename='js/jquery.popper.js') }}"></script>
        为方便使用宏加载静态文件
        例子:
        {% macro static_file(type,filename_or_url,local = True) %}
        {% if local %}
            {% set filename_or_url = url_for('static',filename=filename_or_url) %}
        {% endif %}
        {% if type == 'css' %}
            <script rel="stylesheet" type="text/css" href="{{ filename_or_url }}"></script>
        {% elif type == 'js' %}
            <script type="text/javascript" src="{{ filename_or_url }}"></script>
        {% elif type == 'icon' %}
            <link rel="icon" href="{{ filename_or_url }}">
        {% endif %}
        {% endmacro %}
        加载
        {% from 'macros.html' import static_file %}
        {{ static_file('icon','favicon.ico') }}
        {{ static_file('css','css/bootstarp.min.css') }}
        {{ static_file('js','js/jquery.slim.min.js') }}
        {{ static_file('js','js/popper.min.js') }}
###消息闪现flash()
    # 消息闪现 使用flash()发送的信息会存储在session中所以需要设置app.secret_key
    
    app.secret_key = 'secret string'
    @app.route('/flash')
    def just_flash():
        flash('欢迎,登录!!')
        return redirect(url_for('index'))
    获取信息使用get_flashed_messages()
    注意当get_flashed_messages()被调用之后session信息被移除页面重载后不会出现该信息。
    {% for msg in get_flashed_messages() %}
        <div class="alert">
            {{ msg }}
        </div>
    {% endfor %}    
###表单数据验证
    1.客户端验证
        使用required来验证
        或者使用bootstrap集成的Bootstrap Validator
        增强用户体验降低服务器负载
        在标签属性中添加required即可实现
    2.服务器端验证
        WTForms验证器
        使用方法
        @app.route('/basic',method=['GET','POST'])
        def basic():
            form = LoginFrom()
            if request.method == 'POST' and form.validate():
                ... # 处理请求
            return render_template('basic.html',form=form) 
        设置错误提示语言
        form = Flask(__name__)
        form.config['WTE_I18N_ENABLED'] = False
        class MyBase(FlaskForm):
            '''
            设置错误提示语言
            '''
            class Mtea:
                locales = ['zh']
###表单渲染宏
    {# 表单渲染 #}
    {% macro form_filed(filed) %}
        {{ filed.label }}<br>
        {{ filed(**kwargs) }}<br>
        {% if filed.errors %}
            {% for error in filed.errors %}
                <small class="error">{{ error }}</small><br>
            {% endfor %}
            
        {% endif %}
    {% endmacro %}
###自定义验证器
    from wtforms.validators import ValidationError
    class IndexFrom(MyBase):
    username = StringField('Username')
    password = PasswordField('Password',validators=[DataRequired(),Length(8,128)])
    remember = BooleanField('Remember Me')
    submit = SubmitField('Log In')
    # 建立验证器以validate_字段名 命名
    def validate_username(form,filed):
        if filed.data  == '':
            raise ValidationError('不能为空!!!')
###工厂函数
    当一个函数返回一个对象时称为工厂函数
###app.route()
    route()装饰器的第一个参数是url规则,用字符串表示以‘/’开头
###app.context_processor用于注册模板上下文处理函数
    用于帮助我们完成统一传入变量的工作,需要返回一个包含变量键值对的字典。
    @app.context_processor
    def inject_foo():
        foo = 'i`m foo'
        return dict(foo=foo)
    
###@app.template_global()定义全局函数


    
###url绑定
    一个视图函数可以绑定多个url,用户访问url时会指向同一个函数
    还可以在url规则中添加变量即 <变量名> 的形式来动态接收传入的变量      

 

posted @ 2020-03-25 11:21  momingQI  阅读(290)  评论(0)    收藏  举报