day96:flask:flask-migrate&flask-session&藍圖Blueprint&藍圖的運行機制

目錄

1.flask-migratehtml

2.flask-sessionpython

3.藍圖:Blueprintmysql

4.藍圖的運行機制redis

1.數據庫遷移:flask-migrate

1.Flask的數據庫遷移

  • 在開發過程當中,須要修改數據庫模型,並且還要在修改以後更新數據庫。最直接的方式就是刪除舊錶,但這樣會丟失數據。sql

  • 更好的解決辦法是使用數據庫遷移框架,它能夠追蹤數據庫模式的變化,而後把變更應用到數據庫中。數據庫

  • 在Flask中可使用Flask-Migrate擴展,來實現數據遷移。而且集成到Flask-Script中,全部操做經過命令就能完成。django

  • 爲了導出數據庫遷移命令,Flask-Migrate提供了一個MigrateCommand類,能夠附加到flask-script的manager對象上。json

2.flask-migrate的安裝

pip install flask-migrate

3.在flask代碼中引入數據庫遷移

from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate,MigrateCommand # 1.引入Migrate和MigrateCommand
from flask_script import Manager,Command

app = Flask(__name__,template_folder='templates')
app.config.from_object(Config)

manage = Manager(app)

db = SQLAlchemy(app)


# 2.建立migrate對象。第一個參數是Flask的實例,第二個參數是Sqlalchemy數據庫實例
migrate = Migrate(app,db)

# 3.manager是Flask-Script的實例,這條語句在flask-Script中添加一個db命令
manage.add_command('db',MigrateCommand)


achieve = db.Table('tb_achievement',
    db.Column('student_id', db.Integer, db.ForeignKey('tb_student.id')),
    db.Column('course_id', db.Integer, db.ForeignKey('tb_course.id'))
)


class Course(db.Model):
    __tablename__ = 'tb_course'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    price = db.Column(db.Numeric(6,2))
    teacher_id = db.Column(db.Integer, db.ForeignKey('tb_teacher.id'))
    students = db.relationship('Student', secondary=achieve, backref='courses', lazy='subquery')

    def __repr__(self):
        return 'Course:%s'% self.name

class Student(db.Model):
    __tablename__ = 'tb_student'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    email = db.Column(db.String(64),unique=True)
    age = db.Column(db.SmallInteger,nullable=False)
    sex = db.Column(db.Boolean,default=1)

    def __repr__(self):
        return 'Student:%s' % self.name

class Teacher(db.Model):
    __tablename__ = 'tb_teacher'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    courses = db.relationship('Course', backref='teacher', lazy='subquery')

    def __repr__(self):
        return 'Teacher:%s' % self.name


@app.route("/")
def index():
    return "ok"

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

4.flask中數據庫遷移經常使用的命令

1.建立遷移版本倉庫flask

# 這個命令會建立migrations文件夾,全部遷移文件都放在裏面。
python main.py db init

2.建立遷移版本倉庫瀏覽器

# 這裏等同於django裏面的 makemigrations,生成遷移版本文件
python main.py db migrate -m 'initial migration'

3.升級遷移版本庫的版本

python main.py db upgrade 

4.降級遷移版本庫的版本

 

 

python main.py db downgrade

5.回滾到指定版本

python manage.py db downgrade 版本號   # 返回到指定版本號對應的版本

6.查看數據庫遷移歷史(可查看數據庫遷移版本號)

python manage.py db history

# 輸出格式:<base> ->  版本號 (head), initial migration

通常數據遷移的步驟是:init-->migrate-->upgrade/downgrade

2.flask-session

flask-session:容許設置session到指定存儲的空間中

安裝命令: https://pythonhosted.org/Flask-Session/

1.flask-session的安裝和配置

pip install flask-Session

使用session以前,必須配置一下配置項:

SECRET_KEY = "*(%#4sxcz(^(#$#8423" # session祕鑰

2.redis保存session的基本配置

from flask import Flask,session
from flask_redis import FlaskRedis
from flask_session import Session
app = Flask(__name__)
redis = FlaskRedis()
session_store = Session()
class Config():
    # DEBUG調試模式
    DEBUG = True

    # json多字節轉unicode編碼
    JSON_AS_ASCII = False

    # 數據庫連接配置
    SECRET_KEY = "*(%#4sxcz(^(#$#8423"

    # 1.session存儲方式爲redis
    SESSION_TYPE = "redis"

    # 2.session保存數據到redis時啓用的連接對象
    SESSION_REDIS = redis

    # 3.若是設置session的生命週期是不是會話期, 爲True,則關閉瀏覽器session就失效
    SESSION_PERMANENT = True

    # 4.是否對發送到瀏覽器上session的cookie值進行加密
    SESSION_USE_SIGNER = True

    # 5.保存到redis的session數的名稱前綴
    SESSION_KEY_PREFIX = "session:"

    # 6.redis的連接配置
    REDIS_URL = "redis://localhost:6379/1"


app.config.from_object(Config) # 將Config類註冊到app上
redis.init_app(app)  # 將flask-redis對象掛載到app上
session_store.init_app(app) # 將flask-session對象掛載到app上


@app.route("/")
def index():
    session["username"] = "xiaoming"
    return "Ok"

@app.route("/get_session")
def get_session():
    print( session["username"] )
    return "ok"

@app.route("/redis1")
def set_redis():
    # redis給集合數據類型/哈希數據類型設置值
    redis.set("username","xiaohuihui")
    redis.hset("brother","zhangfei","17")
    return "ok"

@app.route("/redis2")
def get_redis():
    user = redis.get("username").decode()

    brother = redis.hgetall("brother")
    print(brother["zhangfei".encode()].decode())

    return "ok"

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

執行程序,訪問127.0.0.1:5000,便可將session值存儲到redis中

如圖所示:

3.SQLAlchemy存儲session的基本配置

from flask import Flask,session
from flask_redis import FlaskRedis
from flask_session import Session
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy()
redis = FlaskRedis()
session_store = Session()

class Config():

    ......
    '''數據庫連接配置'''
    # SQLALCHEMY_DATABASE_URI = "mysql://帳號:密碼@IP/數據庫名?編碼"
    SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/students?charset=utf8mb4"
    
    # 動態追蹤修改設置,如未設置只會提示警告
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    
    # 查詢時會顯示原始SQL語句
    SQLALCHEMY_ECHO = True

    '''數據庫保存session'''
    SESSION_TYPE = 'sqlalchemy'  # session類型爲sqlalchemy
    SESSION_SQLALCHEMY = db  # SQLAlchemy對象
    SESSION_SQLALCHEMY_TABLE = 'tb_session'  # session要保存的表名稱
    SESSION_PERMANENT = True  # 若是設置爲True,則關閉瀏覽器session就失效。
    SESSION_USE_SIGNER = False  # 是否對發送到瀏覽器上session的cookie值進行加密
    SESSION_KEY_PREFIX = 'session:'  # 保存到session中的值的前綴

db.init_app(app)
app.config.from_object(Config)
redis.init_app(app)
session_store.init_app(app)

@app.route("/")
def index():
    session["username"] = "xiaohui"
    return "Ok"

@app.route("/get_session")
def get_session():
    return session["username"]

if __name__ == '__main__':
    # with app.app_context():
    #     db.create_all()
    app.run()

執行程序,訪問127.0.0.1:5000,便可將session值存儲到mysql中

如圖所示:

3.藍圖:Blueprint

1.藍圖:模塊化

隨着flask程序愈來愈複雜,咱們須要對程序進行模塊化的處理,以前學習過python的模塊化管理,因而針對一個簡單的flask程序進行模塊化處理

簡單來講,Blueprint 是一個存儲視圖方法的容器,這些操做在這個Blueprint 被註冊到一個應用以後就能夠被調用,Flask 能夠經過Blueprint來組織URL以及處理請求。

Flask使用Blueprint讓應用實現模塊化,在Flask中,Blueprint具備以下屬性:

  • 一個項目能夠具備多個Blueprint

  • 能夠將一個Blueprint註冊到任何一個未使用的URL下好比 「/」、「/sample」或者子域名

  • 在一個應用中,一個模塊能夠註冊屢次

  • Blueprint能夠單獨具備本身的模板、靜態文件或者其它的通用操做方法,它並非必需要實現應用的視圖和函數的

  • 在一個應用初始化時,就應該要註冊須要使用的Blueprint

可是一個Blueprint並非一個完整的應用,它不能獨立於應用運行,而必需要註冊到某一個應用中。

Blueprint對象用起來和一個應用/Flask對象差很少,最大的區別在於一個 藍圖對象沒有辦法獨立運行,必須將它註冊到一個應用對象上才能生效.

2.簡單使用藍圖

1.建立一個藍圖的包,例如users,並在__init__.py文件中建立藍圖對象

from flask import Blueprint
# 1. 建立藍圖目錄並對藍圖對象進行初始化
users_blue = Blueprint("users",__name__,template_folder="users_templates",static_folder='users_static',static_url_path="/libs")

2.在這個藍圖目錄下, 建立views.py文件,保存當前藍圖使用的視圖函數

from . import users_blue
from flask import render_template
# 2. 編寫視圖
@users_blue.route("/")
def index():
    return render_template("index.html",title="users/index/index.html")

@users_blue.route("/list")
def list():
    return "users/list"

3.users/__init__.py中引入views.py中全部的視圖函數

# 3. 註冊視圖
from .views import *

4.在主應用main.py文件中的app對象上註冊這個users藍圖對象

# 4. 註冊藍圖
from users import users_blue
app.register_blueprint(users_blue,url_prefix="/users")

當這個應用啓動後,經過/users/能夠訪問到藍圖中定義的視圖函數

3.藍圖的url前綴

當咱們在應用對象上註冊一個藍圖時,能夠指定一個url_prefix關鍵字參數(這個參數默認是/)

  • 在應用最終的路由表 url_map中,在藍圖上註冊的路由URL自動被加上了這個前綴,這個能夠保證在多個藍圖中使用相同的URL規則而不會最終引發衝突,只要在註冊藍圖時將不一樣的藍圖掛接到不一樣的自路徑便可

  • url_for在使用時,若是要生成一個藍圖裏面的視圖對應的路由地址,則須要聲明當前藍圖名稱+視圖名稱

url_for('users.home') # /users/home

4.註冊藍圖的靜態文件的相關路由

1.static_folder:設置靜態文件目錄

和應用對象不一樣,藍圖對象建立時不會默認註冊靜態目錄的路由。須要咱們在 建立時指定 static_folder 參數。

下面的示例將藍圖所在目錄下的static_users目錄設置爲靜態目錄

from flask import Blueprint
# 經過static_folder參數設置靜態文件目錄
users_blue = Blueprint("users",__name__,static_folder='users_static')

 

2.static_url_path:改變靜態文件的路由

定製靜態目錄URL規則 :能夠在建立藍圖對象時使用 static_url_path 來改變靜態目錄的路由。

下面的示例將爲 users/static 文件夾的路由設置爲 /lib

 

from flask import Blueprint
# 經過static_url_path設置靜態文件路由
users_blue = Blueprint("users",__name__,static_folder='users_static',static_url_path='/lib')

訪問http://127.0.0.1:5000/users/libs/1.jpg 便可查看到圖片

5.設置藍圖中模板的目錄

藍圖對象默認的模板目錄爲系統的模版目錄,能夠在建立藍圖對象時使用 template_folder 關鍵字參數設置模板目錄

users_blue = Blueprint("users",__name__,static_folder='users_static',static_url_path='/libs',template_folder='users_templates')

注意:若是在 templates 中存在和 templates_users 有同名模板文件時, 則系統會優先使用 templates 中的文件

4.藍圖的運行機制

1.藍圖運行機制的簡要介紹

  • 藍圖是保存了一組未來能夠在應用對象上執行的操做,註冊路由就是一種操做

  • 當在app對象上調用 route 裝飾器註冊路由時,這個操做將修改對象的url_map路由表

  • 然而,藍圖對象根本沒有路由表,當咱們在藍圖對象上調用route裝飾器註冊路由時,它只是在內部的一個延遲操做記錄列表defered_functions中添加了一個項

  • 當執行app對象的 register_blueprint() 方法時,應用對象將從藍圖對象的 defered_functions 列表中取出每一項,並以自身做爲參數執行該匿名函數,即調用應用對象的 add_url_rule() 方法,這將真正的修改應用對象的usr_map路由表

2.藍圖運行機制的詳細介紹

相關文章
相關標籤/搜索