Flask藍圖,Session,閃現,中間件等

Session

除請求對象以外,還有一個 session 對象。它容許你在不一樣請求間存儲特定用戶的信息。它是在 Cookies 的基礎上實現的,而且對 Cookies 進行密鑰簽名要使用會話,你須要設置一個密鑰。html

設置:session['username'] = 'xxx'java

刪除:session.pop('username', None)python

from flask import Flask,url_for,session

app = Flask(__name__)
app.secret_key = "sdsfdgdgdgd"
app.config['SESSION_COOKIE_NAME'] = 'session_lvning'  #設置session的名字

@app.route('/index/')
def index(nid):
    #session本質上操做的是字典, 全部對session操做的方法與字典方法相同
    #session的原理:若是下一次訪問的時候帶着隨機字符串,會把session裏面對應的
    # 值拿到內存,假設session保存在數據庫,每執行一次連接一次數據庫,每次都要時時更新的話,會很是損耗數據庫的效率
    session["xxx"] = 123
    session["xxx2"] = 123
    session["xxx3"] = 123
    session["xxx4"] = 123
    del session["xxx2"]  #在這刪除了,真正存儲的時候是沒有xxx2的
    return "ddsf"

if __name__ == '__main__':
    app.run()

關於session的配置redis

app.config['SESSION_COOKIE_NAME'] = 'session_lvning'數據庫

- session超時時間如何設置?      'PERMANENT_SESSION_LIFETIME':           timedelta(days=31)
 如下是跟session相關的配置文件
"""
            'SESSION_COOKIE_NAME':                  'session',
            'SESSION_COOKIE_DOMAIN':                None,
            'SESSION_COOKIE_PATH':                  None,
            'SESSION_COOKIE_HTTPONLY':              True,
            'SESSION_COOKIE_SECURE':                False,
            'SESSION_REFRESH_EACH_REQUEST':         True,  #是否每次都跟新
            'PERMANENT_SESSION_LIFETIME':           timedelta(days=31)

基本使用django

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

自定義Sessionjson

pip3 install Flask-Session

        run.py
            from flask import Flask
            from flask import session
            from pro_flask.utils.session import MySessionInterface
            app = Flask(__name__)

            app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
            app.session_interface = MySessionInterface()

            @app.route('/login.html', methods=['GET', "POST"])
            def login():
                print(session)
                session['user1'] = 'alex'
                session['user2'] = 'alex'
                del session['user2']

                return "內容"

            if __name__ == '__main__':
                app.run()

        session.py
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            import uuid
            import json
            from flask.sessions import SessionInterface
            from flask.sessions import SessionMixin
            from itsdangerous import Signer, BadSignature, want_bytes


            class MySession(dict, SessionMixin):
                def __init__(self, initial=None, sid=None):
                    self.sid = sid
                    self.initial = initial
                    super(MySession, self).__init__(initial or ())


                def __setitem__(self, key, value):
                    super(MySession, self).__setitem__(key, value)

                def __getitem__(self, item):
                    return super(MySession, self).__getitem__(item)

                def __delitem__(self, key):
                    super(MySession, self).__delitem__(key)



            class MySessionInterface(SessionInterface):
                session_class = MySession
                container = {}

                def __init__(self):
                    import redis
                    self.redis = redis.Redis()

                def _generate_sid(self):
                    return str(uuid.uuid4())

                def _get_signer(self, app):
                    if not app.secret_key:
                        return None
                    return Signer(app.secret_key, salt='flask-session',
                                  key_derivation='hmac')

                def open_session(self, app, request):
                    """
                    程序剛啓動時執行,須要返回一個session對象
                    """
                    sid = request.cookies.get(app.session_cookie_name)
                    if not sid:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    signer = self._get_signer(app)
                    try:
                        sid_as_bytes = signer.unsign(sid)
                        sid = sid_as_bytes.decode()
                    except BadSignature:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    # session保存在redis中
                    # val = self.redis.get(sid)
                    # session保存在內存中
                    val = self.container.get(sid)

                    if val is not None:
                        try:
                            data = json.loads(val)
                            return self.session_class(data, sid=sid)
                        except:
                            return self.session_class(sid=sid)
                    return self.session_class(sid=sid)

                def save_session(self, app, session, response):
                    """
                    程序結束前執行,能夠保存session中全部的值
                    如:
                        保存到resit
                        寫入到用戶cookie
                    """
                    domain = self.get_cookie_domain(app)
                    path = self.get_cookie_path(app)
                    httponly = self.get_cookie_httponly(app)
                    secure = self.get_cookie_secure(app)
                    expires = self.get_expiration_time(app, session)

                    val = json.dumps(dict(session))

                    # session保存在redis中
                    # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
                    # session保存在內存中
                    self.container.setdefault(session.sid, val)

                    session_id = self._get_signer(app).sign(want_bytes(session.sid))

                    response.set_cookie(app.session_cookie_name, session_id,
                                        expires=expires, httponly=httponly,
                                        domain=domain, path=path, secure=secure)

第三方sessionflask

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
pip3 install redis
pip3 install flask-session

"""


from flask import Flask, session, redirect
from flask.ext.session import Session


app = Flask(__name__)
app.debug = True
app.secret_key = 'asdfasdfasd'


app.config['SESSION_TYPE'] = 'redis'
from redis import Redis
app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')
Session(app)


@app.route('/login')
def login():
    session['username'] = 'alex'
    return redirect('/index')


@app.route('/index')
def index():
    name = session['username']
    return name


if __name__ == '__main__':
    app.run()

Django和Flask中session的區別cookie

Django中,session保存在服務端的數據庫中,數據庫中保存請求用戶的全部數據,服務端數據中{'隨機字符串':加密後的客戶相關信息}
請求完成後,把隨機字符串做爲值,返回給客戶端,保存在客戶端的cookie中,鍵爲:sessionid,值爲:服務端返回的隨機字符串;即{'sessionid':'隨機字符串'}session

Flask中,服務端什麼都不存,用戶第一次請求時,在內存中生成一個空字典,將這個空字典加密後,返回給客戶端,保存在客戶端的cookie中,鍵爲’session',值爲:加密後的字典
下次訪問時,讀取客戶端cookie中key爲session對應的值
而後進行解密(若是不能按以前的的加密方式對應個解密方式解密,即認爲第一次請求,從新生成空字典),解密成功後,能夠對字典進行操做,保存新數據在字典中,請求完成後,會從新加密這個字典,返回個客戶端保存

藍圖(flask中多py文件拆分都要用到藍圖)

若是代碼很是多,要進行歸類。不一樣的功能放在不一樣的文件,吧相關的視圖函數也放進去。藍圖也就是對flask的目錄結構進行分配(應用於小,中型的程序)

藍圖用於爲應用提供目錄劃分:

小中型:

Flask藍圖,Session,閃現,中間件等

manage.py

import fcrm
if __name__ == '__main__':
    fcrm.app.run()

__init__.py(只要一導入fcrm就會執行init.py文件)

from flask import Flask
#導入accout 和order
from fcrm.views import accout
from fcrm.views import order
app = Flask(__name__)
print(app.root_path)  #根目錄

app.register_blueprint(accout.accout)  #把藍圖註冊到app裏面,accout.accout是建立的藍圖對象
app.register_blueprint(order.order)

accout.py

from flask import  Blueprint,render_template
accout = Blueprint("accout",__name__)

@accout.route('/accout')
def xx():
    return "accout"

@accout.route("/login")
def login():
    return render_template("login.html")

order.py

from flask import Blueprint
order = Blueprint("order",__name__)

@order.route('/order')
def register():   
    return "order

大型:

Flask藍圖,Session,閃現,中間件等

Flask藍圖,Session,閃現,中間件等

Flask藍圖,Session,閃現,中間件等

注意:
藍圖中的視圖函數的名字不能和藍圖對象的名字同樣!!!

其餘:

藍圖URL前綴:xxx = Blueprint('account', __name__,url_prefix='/xxx')
藍圖子域名:xxx = Blueprint('account', __name__,subdomain='admin')
# 前提須要給配置SERVER_NAME: app.config['SERVER_NAME'] = 'hc.com:5000'
# 訪問時:admin.hc.com:5000/login.html

閃現(flash)

session存在在服務端的一個字典裏面,session保存起來,取一次裏面仍是有的,直到你刪除以後纔沒有了

一、本質

flash是基於session建立的,flash支持往裏邊放值,只要你取一下就沒有了,至關於pop了一下。不只能夠拿到值,並且能夠把其從session裏的去掉,
基於Session實現的用於保存數據的集合,其特色是:使用一次就刪除。

二、閃現的用途
某個數據僅需用一次時,能夠使用閃現

from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'

@app.route('/users')
def users():
    # 方式一
    # msg = request.args.get('msg','')
    # 方式二
    # msg = session.get('msg')
    # if msg:
    #     del session['msg']
    # 方式三
    v = get_flashed_messages()  # 獲取flash中的值
    print(v)
    msg = ''
    return render_template('users.html',msg=msg)

@app.route('/useradd')
def user_add():
    # 在數據庫中添加一條數據
    # 假設添加成功,在跳轉到列表頁面時,顯示添加成功
    # 方式一
    # return redirect('/users?msg=添加成功')
    # 方式二
    # session['msg'] = '添加成功'
    # 方式三
    flash('添加成功')
    return redirect('/users')


if __name__ == '__main__':
    app.run(debug=True)

中間件

在函數執行以前或函數執行以後想作點事情,有2種方式

第一種:裝飾器

第二種:flask裏面的擴展,至關於django中的中間件

from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'

@app.before_request
def process_request1():
    print('process_request1')

@app.after_request
def process_response1(response):
    print('process_response1')
    return response


@app.before_request
def process_request2():
    print('process_request2')

@app.after_request
def process_response2(response):   #參數也得有
    print('process_response2')
    return response   #必須有返回值


@app.route('/index')
def index():
    print('index')
    return 'Index'

@app.route('/order')
def order():
    print('order')
    return 'order'

@app.route('/test')
def test():
    print('test')
    return 'test'

if __name__ == '__main__':
    app.run()

運行結果:

Flask藍圖,Session,閃現,中間件等

還有一個@app.before_first_request:表示,當程序運行起來,第一個請求來的時候就只執行一次,下次再來就不會在執行了

請求擴展

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, Request, render_template

app = Flask(__name__, template_folder='templates')
app.debug = True


@app.before_first_request    # 只在第一次請求到來時執行一次,後面不會再執行
def before_first_request1():
    print('before_first_request1')


@app.before_first_request
def before_first_request2():
    print('before_first_request2')


@app.before_request    # 每次請求到來時,都會執行
def before_request1():
    Request.nnn = 123
    print('before_request1')


@app.before_request
def before_request2():
    print('before_request2')


@app.after_request    # 每次響應時執行
def after_request1(response):
    print('before_request1', response)
    return response


@app.after_request
def after_request2(response):
    print('before_request2', response)
    return response


@app.errorhandler(404)
def page_not_found(error):
    return 'This page does not exist', 404


@app.template_global()    # 自定義標籤,全部頁面都直接使用
def sb(a1, a2):
    return a1 + a2


@app.template_filter()    # 自定義過濾器,全部頁面都直接使用
def db(a1, a2, a3):
    return a1 + a2 + a3


@app.route('/')    # 訪問的url,不加其餘後綴時,也要有/
def hello_world():
    return render_template('hello.html')


if __name__ == '__main__':
    app.run()

自定義標籤和過濾器在頁面上的調用方式:{{sb(1,2)}}  {{ 1|db(2,3)}}

編寫統一的404頁面

導入abort方法
    from flask import abort

設置一個站位符,當404錯誤出現時,本身編寫的404頁面就會在佔位符的位置進行顯示
    abort(404)  

利用鉤子編寫本身的404頁面

@app.errorhandler(404)  # 404頁面鉤子
def page_404(er):  # 參數是原始的404頁面提示信息
  print(er)
  return '這是統一的錯誤頁面', 404, {}  # 返回本身編寫的404頁面信息

Flask藍圖,Session,閃現,中間件等


from flask import Flask
from flask import abort

app = Flask(__name__)

@app.route('/')
def index():
    return '測試主頁面'

movies = [1,2,3,4,5]

@app.route('/movie/<int:num>/')
def movie(num):
    if num in movies:
        return '電影 {} 的詳細信息爲:...... '.format(num)
    abort(404)  # 本身編寫的404頁面會顯示在這裏

@app.errorhandler(404)  # 404頁面鉤子
def page_404(er):  # 參數是原始的404頁面提示信息
    print(er)
    return '這是統一的錯誤頁面', 404, {}  # 返回本身編寫的404頁面信息


print(app.url_map)

if __name__ == '__main__':
    app.run(debug=True)

 

原文連接:

https://www.cnblogs.com/huchong/p/8227606.html

 


 

Flask藍圖,Session,閃現,中間件等

識別圖中二維碼,領取python全套視頻資料

相關文章
相關標籤/搜索