zoukankan      html  css  js  c++  java
  • Flask详解(中篇)

    一 Flask请求和响应

    from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response
    
    app = Flask(__name__)
    
    
    @app.route('/login.html', methods=['GET', "POST"])
    def login():

    请求相关信息

    # request.method
    # request.args          获取GET方式的url参数
    # request.form          form提交的数据取值
    # request.values        同时获得form和args的值
    # request.json          请求头是contenttype:application/json 将字典序列化成jason
    # request.data          contenttype请求无法解析时会以byte放入data
    # 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
    # obj = request.files['the_file_name']
    # obj.save('/var/www/uploads/' + secure_filename(f.filename))

    响应相关信息

    # return "字符串"
    # return render_template('html模板路径',**{})
    # return redirect('/index.html')
    
    
    # response = make_response(render_template('index.html'))
    # response是flask.wrappers.Response类型
    # response.delete_cookie('key')
    # response.set_cookie('key', 'value')
    # response.headers['X-Something'] = 'A value'
    # return response
    # return jsonfiy                 返回序列化的json数据
    # return send_file(file_name)   返回一个文件

    二 模板语言

    1、模板的使用

    Flask使用的是Jinja2模板,所以其语法和Django无差别

    2、自定义模板方法

    Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,如:

    from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response,Markup
    from urllib.parse import urlencode,quote,unquote
    app = Flask(__name__)
    
    def test(a1,a2):
        return a1+a2
    
    @app.template_global()
    def sb(a1,a2):
        return a1 + a2 + 100
    
    
    @app.template_filter()
    def db(a1, a2, a3):
        return a1 + a2 + a3
    
    
    @app.route('/index',endpoint='xx')
    def index():
        v1 = "字符串"
        v2 = [11,22,33]
        v3 = {'k1':'v1','k2':'v2'}
        v4 = Markup("<input type='text' />")
        return render_template('index.html',v1=v1,v2=v2,v3=v3,v4=v4,test=test)
    
    '''
    函数模板
    '''
    from common.libs.UrlManager import UrlManager
    
    app.add_template_global(UrlManager.buildStaticUrl, 'buildStaticUrl')
    app.add_template_global(UrlManager.buildUrl, 'buildUrl')
    app.add_template_global(UrlManager.buildImageUrl, 'buildImageUrl')
    
    if __name__ == '__main__':
        # app.__call__
        app.run()

    layout.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>模板</h1>
        {%block body %} {%endblock%}
    
    </body>
    </html>

    index.html

    {% extends 'layout.html'%}
    
    {%block body %}
        {{v1}}
    
        <ul>
            {% for item in v2 %}
            <li>{{item}}</li>
            {% endfor %}
        </ul>
        {{v2.1}}
    
        <ul>
            {% for k,v in v3.items() %}
            <li>{{k}}  {{v}}</li>
            {% endfor %}
        </ul>
        {{v3.k1}}
        {{v3.get('k1')}}
    
        {{v4}}
        <!--{{v4|safe}}-->
    
        <h1>{{test(1,19)}}</h1>
    
        {{sb(1,2)}}
    
        {{ 1|db(2,3)}}
    
    
        {% macro xxxx(name, type='text', value='') %}
            <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
            <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
            <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
            <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
        {% endmacro %}
    
        {{ xxxx('n1') }}
    
    
    {%endblock%}

    三 session

    当请求刚到来时:Flask会读取cookie中session对应的值。 将这个值解密并反序列化成字典放入内存以便视图函数使用

    视图函数:

    @app.route('/ses')
    def ses():
        session['k1'] = 123
        session['k2'] = 456
        del session['k1']
        return session

    # 注意要在使用之前设置secret key 

    app.secret_key = 'sdfsdfsdf'

    当请求结束时,Flask会读取内存中字典的值,进行序列化+加密,再写入到用户的cookie中

    四 闪现

    闪现是指在session中存储一个数据,读取时通过pop将数据移除

    from flask import Flask,flash,get_flashed_messages
    
    @app.route('/page1')
    def page1():
        flash('临时数据存储', 'error')
        flash('sdfsdfsdffsdf', 'error')
        flash('asdfsdfsdfdsf', 'info')
        
        return "Session"
    
    @app.route('/page2')
    def page2():
        print(get_flashed_messages(category_filter=['error']))
        return "Session"

     五 中间件

    在call方法执行之前加入其它功能,实现类似中间件的功能
    from flask import Flask, flash, redirect, render_template, request
    app = Flask(__name__)
    app.secret_key = 'some_secret'
     
    @app.route('/')
    def index1():
        return render_template('index.html')
     
    @app.route('/set')
    def index2():
        v = request.args.get('p')
        flash(v)
        return 'ok'
     
    class MiddleWare:
        def __init__(self,wsgi_app):
            self.wsgi_app = wsgi_app
     
        def __call__(self, *args, **kwargs):
            #  在call方法执行之前加入其它功能,实现类似中间件的功能
            return self.wsgi_app(*args, **kwargs)
     
    if __name__ == "__main__":
        app.wsgi_app = MiddleWare(app.wsgi_app)
        app.run(port=9999)

    六 特殊装饰器

    • - before_firset_request
    • - before_request # 再请求进入视图函数之前做出处理
    • - after_request # 再请求结束视图函数之后,返回客户端之前 def go(response) return response 逆向执行    # 正常场景be1-be2-af2-af1 异常场景 be1-af2-af1
    • - template_global()
    • - template_filter()
    • - errorhandler (404) # 在使用errorheadler传递参数 404 500 error(code_or_exp) return redirect("/index")

     拦截验证用户是否登录的方法:

    # -*- coding: utf-8 -*-
    from application import app
    from flask import request,g,redirect
    
    from common.models.User import ( User )
    from common.libs.user.UserService import ( UserService )
    from common.libs.UrlManager import ( UrlManager )
    from common.libs.LogService import LogService
    import  re
    @app.before_request
    def before_request(): ignore_urls = app.config['IGNORE_URLS'] ignore_check_login_urls = app.config['IGNORE_CHECK_LOGIN_URLS'] path = request.path # 如果是静态文件就不要查询用户信息了 pattern = re.compile('%s' % "|".join(ignore_check_login_urls)) if pattern.match(path): return if '/api' in path: return user_info = check_login() g.current_user = None if user_info: g.current_user = user_info # #加入日志 # LogService.addAccessLog() pattern = re.compile('%s' % "|".join(ignore_urls)) if pattern.match(path): return if not user_info : return redirect( UrlManager.buildUrl( "/user/login" ) ) return ''' 判断用户是否已经登录 ''' def check_login(): cookies = request.cookies auth_cookie = cookies[app.config['AUTH_COOKIE_NAME']] if app.config['AUTH_COOKIE_NAME'] in cookies else None if '/api' in request.path: app.logger.info(request.path) auth_cookie = request.headers.get("Authorization") app.logger.info( request.headers.get("Authorization") ) if auth_cookie is None: return False auth_info = auth_cookie.split("#") if len(auth_info) != 2: return False try: user_info = User.query.filter_by(uid=auth_info[1]).first() except Exception: return False if user_info is None: return False if auth_info[0] != UserService.geneAuthCode( user_info ): return False if user_info.status != 1: return False return user_info

    404错误拦截

    # -*- coding: utf-8 -*-
    from application import app
    from common.libs.Helper import ops_render
    from common.libs.LogService import LogService
    
    @app.errorhandler(404)
    def error_404(e):
        LogService.addErrorLog(str(e))
        return ops_render('error/error.html', {'status': 404, 'msg': '很抱歉!您访问的页面不存在'})

    七 蓝图

    简单来说,Blueprint 是一个存储操作方法的容器,这些操作在这个Blueprint 被注册到一个应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。

    Flask使用Blueprint让应用实现模块化,在Flask中,Blueprint具有如下属性:

    • 一个应用可以具有多个Blueprint
    • 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名
    • 在一个应用中,一个模块可以注册多次
    • Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
    • 在一个应用初始化时,就应该要注册需要使用的Blueprint

    但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

    使用蓝图的实例:

      

    结构:
    Mycrm
      crm
        static
        template
          login.html
        views
          account.py
          order.py
        models.py
        __init__.py
      manage.py
      settings.py

      

    __init__.py:

    from flask import Flask
    from .views import account
    from .views import order
    
    app = Flask(__name__)
    print(app.root_path)
    # 注意一定要注册注册蓝图
    app.register_blueprint(account.account)
    app.register_blueprint(order.order)

    manage.py:

    import crm
    if __name__ == '__main__'
        mycrm.app.runn()

    account.py:

    from flask import Blueprint,render_template
    account = Blueprint('account',__name__,)
    
    @account.route('/login')
    def login():
        # return 'Login'
        return render_template('login.html')

    order.py:

    from flask import Blueprint
    
    order = Blueprint('order',__name__)
    @order.route('/order')
    def login():
        return 'Order'
  • 相关阅读:
    jquery从零开始(一)
    Android第三次作业
    Android第一次作业
    团队作业-项目答辩
    软工第二次作业
    软工团队第二次作业
    bug killer 团队
    软件工程第一次作业
    Android第四次作业
    Android第三次作业
  • 原文地址:https://www.cnblogs.com/harryblog/p/11159142.html
Copyright © 2011-2022 走看看