python-flask筆記(六)

此章和教程出入不大,可直接看原教程

  • 之前寫的代碼耦合太重,python也可以像js模塊化一樣模塊化程序結(jié)構

模塊化

  • 使用 藍圖(藍本),我們之前的程序都有一個Flask的實例
app = Flask(__name__)
  • 這個app變量可以定義路由,藍圖就是可以將路由分門別類,然后在組合在一起
  • 需要重新設置一下目錄結(jié)構:
.
├── app
│   ├── admin
│   │   ├── errors.py
│   │   ├── forms.py
│   │   ├── __init__.py
│   │   └── views.py
│   ├── __init__.py
│   ├── main
│   │   ├── forms.py
│   │   ├── __init__.py
│   │   └── views.py
│   ├── models.py
│   ├── static
│   └── templates
│       ├── 404.html
│       ├── 500.html
│       ├── admin
│       │   ├── login.html
│       │   └── register.html
│       ├── base.html
│       ├── index.html
│       └── user.html
├── config.py
├── manage.py
  • Flask 程序一般都保存在名為app的包中.
  • config.py 保存著配置
  • manage.py 用于啟動項目

說明一下python 的包(package),從目錄結(jié)構上看,python的package有兩部分組成: 文件夾和init.py 文件. 正是因為init.py 的存在 python編譯器才會把那個文件夾當作是一個python的包來看待. 而那個 init.py 的效果就是, 能夠有一個與包名字相同的文件. 什么意思呢?
比如 我們有一個名字為 main 的包, 那么

from main import *

這行代碼中,從main包中import所有的東西,你想啊,main是個包,import進來是啥??? 其實阿,import進來的是init.py中的內(nèi)容.

  • 把原先那個blog.py中的東西復制一下就好了:
    • config.py:
import os

basedir = os.path.abspath(os.path.dirname(__file__))


class Config:
    SECRET_KEY = 'a string'
    # 數(shù)據(jù)庫配置
    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
    SQLALCHEMY_COMMIT_TEARDOWN = True
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    @staticmethod
    def init_app(app):
        pass

仿照狗書,創(chuàng)建一個程序工廠函數(shù). 設計模式中有一個模式叫做:工廠模式,比如你需要一個東西,但這個東西你需要配置很多,這樣你就可以用到工廠模式,在把配置(比如汽車廠,把各個零件組裝起來)的活交給工廠,那么工廠出來的產(chǎn)品就是好的產(chǎn)品.這樣可以降低程序的耦合度,怎么理解呢,如果這個產(chǎn)品是壞的,那么你也不需要到處去程序的代碼,只需要去那個工廠的程序中去尋找bug就好了

程序工廠函數(shù):

說一下工廠函數(shù),我們之前單個文件開發(fā)程序很方便,但卻有個很大的缺點,因為程序在全局作用中創(chuàng)建,所以無法動態(tài)修改配置.運行腳本時,實例已經(jīng)創(chuàng)建,再修改配置為時已晚,解決問題的方法就是延遲創(chuàng)建程序?qū)嵗?把創(chuàng)建過程移到可顯式調(diào)用的工廠函數(shù)中.

  • app/init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

from config import Config

db = SQLAlchemy()


def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    Config.init_app(app)

    db.init_app(app)

    return app

這段代碼,我們的db實例,先于app創(chuàng)建,app的創(chuàng)建只能調(diào)用了create_app()函數(shù)之后才創(chuàng)建.

藍圖:

Flask 中的藍圖為這些情況設計:

  • 把一個應用分解為一個藍圖的集合。這對大型應用是理想的。一個項目可以實例化一個應用對象,初始化幾個擴展,并注冊一集合的藍圖。
  • 以 URL 前綴和/或子域名,在應用上注冊一個藍圖。 URL 前綴/子域名中的參數(shù)即成為這個藍圖下的所有視圖函數(shù)的共同的視圖參數(shù)(默認情況下)。
  • 在一個應用中用不同的 URL 規(guī)則多次注冊一個藍圖。
  • 通過藍圖提供模板過濾器、靜態(tài)文件、模板和其它功能。一個藍圖不一定要實現(xiàn)應用或者視圖函數(shù)。
  • 初始化一個 Flask 擴展時,在這些情況中注冊一個藍圖。

藍圖問題,最后總結(jié):

  • 在藍本中定義的路由處于休眠狀態(tài),直到藍本注冊到程序上后,路由才真正成為程序的一部分

創(chuàng)建藍本:

  • app/main/init
from flask import Blueprint

main = Blueprint('main', __name__)

from . import views, errors

藍圖是通過實例化Blueprint類對象來創(chuàng)建的。這個類的構造函數(shù)接收兩個參數(shù):藍圖名和藍圖所在的模塊或包的位置。與應用程序一樣,在大多數(shù)情況下,對于第二個參數(shù)值使用Python的name變量即可。

應用程序的路由都保存在app/main/views.py模塊內(nèi)部,而錯誤處理程序則保存在app/main/errors.py中。導入這些模塊可以使路由、錯誤處理與藍圖相關聯(lián)。重要的是要注意,在app/init.py腳本的底部導入模塊要避免循環(huán)依賴,因為view.py和errors.py都需要導入main藍圖

注冊藍圖:

  • app/init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

from config import Config

db = SQLAlchemy()


def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    Config.init_app(app)

    db.init_app(app)

    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)
    #通過register_blueprint方法將藍圖注冊進來
    
    return app
  • app/main/errors.py:
from flask import render_template

from . import main


@main.app_errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404


@main.app_errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500
  • app/main/views.py:
from flask import render_template
from flask import session
from flask import redirect
from flask import url_for
from flask import request

from . import main
from ..models import User
from .. import db


@main.route('/', methods=['GET', 'POST'])
def index():
    if 'name' in request.args:
        name = request.args['name']
        return render_template('user.html', username=name)
    else:
        return render_template('index.html')


@main.route('/register', methods=['POST'])
def register():
    username = request.form['username']
    password = request.form['password']

    if username:
        user = User.query.filter_by(name=username)
        if user is None:
            ##添加進數(shù)據(jù)庫
            user = User(name=username)
            ##如果沒有app.config['SQLALCHEMY_COMMIT_TEARDOWN'] = True
            ##這句后面還要加上db.session.commit()才會提交到數(shù)據(jù)庫
            db.session.add(user)
            session['known'] = False
        else:
            session['known'] = True
        session['name'] = username

    name=session.get('name')
    return '你的用戶名是 %s' % name
  • manage.py:
from flask_script import Manager

from app import create_app, db

app = create_app()
manager = Manager(app)

if __name__ == '__main__':
    manager.run()
  • app/models.py:
from . import db


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    # 如果你學過數(shù)據(jù)庫的話就知道我們一般通過id來作為主鍵,來找到對應的信息的,通過id來實現(xiàn)唯一性
    name = db.Column(db.String(64), unique=True)

    def __repr__(self):
        return 'users表: id為:{}, name為:{}'.format(self.id, self.name)
  • 在終端輸入:
python manage.py shell
>>> from manage import *
>>> db
<SQLAlchemy engine=sqlite:////home/me/PycharmProjects/blog/data.sqlite>
>>> db.drop_all()
>>> db.create_all()
>>> exit()
  • 這里把表重新創(chuàng)建了一下,因為表已經(jīng)移動位置了.
    然后:
python manage.py runserver

然后就可以正常運行了

運行的時候注意有沒有更改端口,改了的話html文件里的請求接口也記得改一下
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • flask是python的一個web應用框架,django很多人聽過,flask比較少見,連創(chuàng)始人一開始寫出來只是...
    思而憂閱讀 3,032評論 0 5
  • 22年12月更新:個人網(wǎng)站關停,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,415評論 22 257
  • 第七章 大型程序架構 雖然在一個腳本里完成一個web應用很便利,但是這也意味著它很難擴展。當程序不斷增長,越來越復...
    易木成華閱讀 1,021評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,590評論 19 139
  • 和身邊的朋友一起進步才是真正的進步。這樣自然而然會留住很多朋友。這樣你們在一起才不會荒廢時間,對于一份工作著重要看...
    李陽_98d1閱讀 152評論 1 0

友情鏈接更多精彩內(nèi)容