天天看點

Python Flask學習知識點(五)

Python Flask學習知識點(五)

timg (9).jpg

從本章開始,逐漸引入資料庫相關知識點。

關于資料庫的工具以及一些入門的知識請自行查找資料學習(例如:建立資料表,資料庫可視化工具)。

資料表建立方式

Python Flask學習知識點(五)

image.png

對于我們開發人員來說,一般推薦使用Code First ,因為可以專注業務模型的設計 而不是資料庫設計 , 資料庫隻是用來存資料的 ,它的表關系應該由我們業務來決定。

那麼其他兩種資料表建立方式可以自己上網查詢相關資料,這裡不再贅述。

定義一個模型類

之前提過一個叫做驗證層,現在引入模型層(MVC中的M:模型層)

設計模型的思維,應該考慮業務模型,而不要去過多注意資料庫的設計,資料庫隻是存資料的。

app檔案夾下建立models檔案夾并建立一個名為book.py的模型:

Python Flask學習知識點(五)

這裡使用sqlalchemy這個包來做模型映射,還有一個包叫做flask_sqlalchemy,是flask在sqlalchemy的基礎上做了一些自己的封裝,待會我們也要用到。

再介紹一個第三方的獨立的包:WTFORMS,Flask也針對這個包做了封裝并有一個新的包叫做Flask_WTFORMS,以上兩個(sqlalchemy、WTFORMS)是獨立的兩個包,可以用在任何時候而不僅僅在Flask中。

Flask的路由是在werkzeug基礎上封裝的

Flask是微架構,隻提供最核心的功能其他部分可以自由組裝

所有flask插件都必須和flask核心對象app綁定在一起

安裝兩個包:

pip install sqlalchemy

pip install flask-sqlalchemy

編輯book.py:

from sqlalchemy import Column, Integer, String
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
class Book(db.Model):
    # 主鍵 自增
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 長度50 不為空
    title = Column(String(50), nullable=False)
    author = Column(String(30), default="未知")
    # unique : 不重複, 會加一個索引, 不重複
    uid= Column(String(15), nullable=False, unique=True)

           

以上代碼就是一個簡單的建立資料表的模型,包含四個字段,

之前提到過,所有的Flask的插件都需要和Flask的核心對象app來關聯起來,那麼怎麼做關聯呢?

在app檔案夾下的

__init__.py

中:

from flask import Flask
from app.models.book import db

def create_app():
    app = Flask(__name__)
    app.config.from_object("app.setting")
    app.config.from_object("app.secure")

    register_blueprint(app)

    db.init_app(app)
    db.create_all(app=app)
    return app


def register_blueprint(app):
    from app.web import web
    app.register_blueprint(web)
           

首先把db對象導入,

再使用db.init_app(app)做關聯,init_app這個方法很重要,後邊所有的Flask插件都使用這個方法做關聯。

接着,

需要把資料庫的配置資訊放到配置檔案中,因為資料庫配置資訊是屬于比較機密的,是以我們放在secure.py中。

SQLALCHEMY_DATABASE_URI = 'mysql+cymysql://root:[email protected]:3306/demo'
           

上邊配置資訊的變量名

SQLALCHEMY_DATABASE_URI

這個是不可以更改的,必須使用這個,

後邊參數的意思是使用cymysql這個驅動來做資料庫操作,使用者名root 密碼 123456,ip 端口是127.0.0.1 3306,資料庫名為demo。

cymysql需要安裝:

pip install cymysql

運作代碼檢視結果,資料庫确實多了一張名為book的表。

ORM與Code First

ORM 對象關系映射 : 包含的層面更廣闊 不僅僅是建立 還包含查詢 更新 删除

Code First : 解決的是資料表建立的問題,專注業務模型設計而不是資料庫設計,資料庫隻是存資料的,表關系應該有業務來決定

業務邏輯最好寫在MVC中M中

Flask中上下文管理

  • 應用上下文(AppContext)
  • 請求上下文(RequestContext)

上下文本質來說其實就是對象

應用上下文:對核心對象Flask的封裝

請求上下文:對請求對象Request的封裝

為什麼會需要上下文?直接操作Flask核心對象不行嗎?

其實這個就是一個設計思想的問題,有時候對于一個對象來說,有一些資訊是屬于這個對象外部的,并不是屬于對象本身,那麼此時我們可以設計一個所謂的上下文(上下文就是一個對象),把Flask核心對象和外部的這些資料一起組成一個整體,這個整體就是我們說的上下文對象。

Flask核心對象:承載着各種各樣的功能,例如:儲存配置檔案資訊、提供注冊路由\視圖函數等這樣的功能。

AppContext :把Flask核心對象做了一系列封裝,并且附加了一些額外的參數

Request :儲存了一些請求資訊,例如: URL參數,完整的URL等等一切的請求資訊都在這個對象中。

RequestContext : 對Request對象的封裝。

在我們編碼過程中,真正想去使用的是Flask核心對象或者是Request這個對象,但是我們要使用它并不一定要直接直接導入這倆核心對象,正确的做法是:

從AppContext或RequestContext間接的去拿Flask核心對象或者是Request。

Flask中,采用了LocalProxy模式(本地代理)的模式提供了間接去操作上下文的能力,也就是current_app和request這兩個對象。

這裡Flask使用了設計模式裡邊的代理模式。

Flask上下文與出入棧

Flask如何操作上下文?看下圖:

Python Flask學習知識點(五)

當一個請求進入Flask架構中時,首先會執行個體化一個RequestContext(請求上下文),這個請求上下文封裝了這次請求的相關資訊,請求的相關資訊在Request中,然後會把請求上下文使用push方法推入到棧中(棧:先入後出),Flask中使用 LocalStack 來表示一個棧,LocalStack 是一個對象,執行個體化之後,用 _request_ctx_stack 來表示RequestContext推入的棧,同樣的,還有一個 _app_ctx_stack 也是一個棧,

RequestContext在入棧之前,Flask會去檢查一下 _app_ctx_stack 這個棧的棧頂的元素,如果是空或者不是目前對象,那麼Flask會把AppContext推入_app_ctx_stack這個棧中

然後才會把RequestContext推入_request_ctx_stack棧中。

current_app(Local Proxy) 和 request(Local Proxy) 永遠都是指向棧頂的,是以當你去使用current_app或request,其實就是在操作這兩個棧的棧頂元素。

欲知後事如何,請看下回分解,記得點個贊~感謝