從零開始用 Flask 搭建一個網站(一)
前言
筆者之前未接觸過 Python,只是略懂一點前端,所以說從零開始也相差無幾吧。Flask 是一個輕量級的基於 Python 的框架,但是擴充套件性非常良好(Github 上 22000 多個 star 就知道群眾的選擇不無道理),其他的這裡就不多提了,下面就開始我們的網站搭建之路。
開始
環境搭建
首先需要準備 Python 開發環境,這裡推薦使用 pyenv 來安裝和管理 Python。筆者使用的是 Mac OSX(自帶 Python 2.6),直接使用如下命令安裝 pyenv:
brew install pyenv
之後要升級 pyenv 的話就用:
brew upgrade pyenv
安裝完以後,需要配置環境變數,如果使用 zsh,需要在 ~/.zshrc 加入以下程式碼:
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export PATH=$PATH:/sbin/
eval "$(pyenv init -)"
如果使用 bash,在 ~/.bash_profile 中加入即可。儲存後重啟終端即可。
如果要安裝 Python 3.5.2,可以用
pyenv install 3.5.2
檢視安裝的 Python 版本:
pyenv versions
切換區域性 Python 環境(這裡一般指在 Application 資料夾下切換環境)
pyenv local 3.5.2
關於其他更多命令,可以參考 Command.md
使用 IDE
這裡筆者推薦使用 PyCharm 來進行 python 專案開發。下載安裝後(這裡筆者下載的是 Professional 版本),新建一個 Flask 專案,然後指定目錄、python 環境:
完成後點選 Create,這樣就建立了一個 Flask 專案,如果沒有安裝 Flask,PyCharm 會自動下載安裝。如果想使用 virtualenv,可以參考下一個步驟。
使用虛擬環境
使用虛擬環境可以方便地安裝 Flask 而且可以在系統的 Python 直譯器中避免包的混亂和版本的衝突。Python 3.3以後原生支援虛擬環境,命令為 pyvenv。可以使用如下命令建立虛擬環境(進入剛才建立的 Flask 專案資料夾):
pyvenv venv
如果使用 Python 2.7或者以下版本,可以使用第三方工具 virtualenv 建立虛擬環境:
sudo easy_install virtualenv
以上命令就可以安裝 virtualenv(如果沒有安裝 easy_install,需要手動安裝,而 pyvenv 已經自帶 pip 和 easy_install)。下一步使用 virtualenv 命令在資料夾中建立 Python 虛擬環境:
virtualenv venv
完成後,會在 Flask 專案下生成 venv 資料夾。在使用虛擬環境之前,要先使用(pyvenv 和 virtualenv 建立的虛擬環境是一樣的,因此以下命令均可使用):
source venv/bin/activate
來啟用,如果要退出虛擬環境,可以使用:
deactivate
建立的虛擬環境會自動安裝 pip 和 easy_install,接下來可以使用:
pip install flask
接下來就可以在 Flask 中開始自由地遨(入)遊(坑)啦!
Flask 程式結構
在介紹 Flask 的程式結構之前,先來看看標準 Flask 專案的專案結構(筆者以為從巨集觀到微觀的方式可以更快的瞭解一個東西)。使用 PyCharm 新建 Flask 專案後,專案結構如下圖所示:
只有三個資料夾(venv 資料夾已經用命令列生成了)和一個簡單的入口類,接下來要把專案結構改造成標準的 Flask 專案結構:
Flask 專案有4個頂級資料夾:
- app ——(本例中是 jbox)Flask 程式儲存在此資料夾中
- migrations ——包含資料庫遷移指令碼(安裝了 flask-migrate 後自動生成)
- tests ——單元測試放在此資料夾下
- venv ——Python 虛擬環境
同時還有一些檔案:
- requirements.txt —— 列出了所有的依賴包,以便於在其他電腦中重新生成相同的環境
- config.py 儲存配置
- manage.py 啟動程式或者其他任務
- gun.conf Gunicorn 配置檔案
雖然新建的 Flask Project 已經可以執行,但是我們還是要按照標準的 Flask 程式來改造專案結構。下面我們就來改造一下 TestProject。
在命令列中依次使用以下命令來安裝 Flask 擴充套件:
pip install flask-script
pip install flask-sqlalchemy
pip install flask-migrate
flask-script 可以自定義命令列命令,用來啟動程式或其它任務;flask-sqlalchemy 用來管理資料庫的工具,支援多種資料庫後臺;flask-migrate 是資料庫遷移工具,該工具命令整合到 flask-script 中,方便在命令列中進行操作。
然後建立 config.py 檔案,內容如下:
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'this is a secret string'
SQLALCHEMY_TRACK_MODIFICATIONS = True
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'dev')
class TestingConfig(config):
TESTING = True
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'test')
class ProductionConfig(config):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'data.sqlite')
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
config 顧名思義,儲存了一些配置變數。SQLALCHEMY_DATABASE_URI 變數在不同的配置中被賦予了不同的值,這樣就可以在不同的環境中切換資料庫。如果是遠端資料庫則從環境變數中讀取 URL,否則在本地路徑中建立。
接下來建立一個 app 資料夾,並在此資料夾中建立一個 __init__.py 檔案(init 前後都有兩個下劃線):
app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
db.init_app(app)
//此處預設了部分程式碼,後面會加上
return app
create_app() 就是程式的工廠函式,引數就是配置類的名字,即 config.py,其中儲存的配置可以使用 from_object() 方法匯入。
接下來要解釋兩個重要的概念——路由和檢視函式。客戶端把請求發給 Web 伺服器,Web 伺服器再把請求發給 Flask 程式例項,Flask 程式例項需要知道每個 URL 請求要執行哪些程式碼,所以儲存了一個 URL 到 Python 函式的對映關係。處理 URL 和函式之間關係的程式稱為路由,這個函式稱為檢視函式。例如:
@app.route('/')
def index():
return '<h1>Hello World</h1>'
這裡使用 app.route 修飾器來定義路由,app 指 Flask 程式例項物件,後面可以看到使用藍本管理路由後,由藍本例項物件來取代 app。Flask 使用藍本來定義路由,在藍本中定義的路由處於休眠狀態,直到藍本註冊到程式上後,路由真正成為程式的一部分。藍本通常使用結構化的方式儲存在包的多個模組中。接下來在 app 資料夾下建立一個子資料夾 main,並在 main 中建立 __init__.py(如果使用 PyCharm,這裡有個快捷方式,右鍵點選 app 資料夾,在選單中選擇 new -> Python Package,在彈出的對話方塊中填寫包名然後確認即可):
app/main/__ init__.py
from flask import Blueprint
//例項化 Blueprint 類,兩個引數分別為藍本的名字和藍本所在包或模組,第二個通常填 __name__ 即可
main = Blueprint('main', __name__)
from . import views, errors
最後引用了兩個檔案,之所以寫在最後是因為避免迴圈匯入依賴,因為接下來在 main 資料夾下 建立的 views.py 和 errors.py 都要匯入藍本 main。
app/main/views.py
from flask import render_template
//匯入藍本 main
from . import main
@main.route('/')
def index():
return render_template('index.html')
在之前路由的概念解釋中,index 函式直接返回了 HTML 字串(通常不這麼做),這裡則使用了 render_templete() 函式來渲染 index.html,並返回。Flask 使用了 Jinja2 引擎來渲染模板,模板檔案都放在 templates 資料夾下,並且只能命名為 templates,否則 Jinja2 會丟擲 TemplageNotFound 異常。由於我們的app 是一個 Python Package(在目錄中包含 __init__.py 預設成為 Python Package),所以需要將 templates 放在 app 目錄下。在 app 下 中建立名為 templates 的資料夾,在 PyCharm 中右鍵點選該資料夾,然後選擇 Make Directory As -> Template Folder,如圖:
接下來在 templates 下新建一個 index.html 和 404.html 模板:
app/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
app/templates/404.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Not Found</title>
</head>
<body>
<h1>Can't find request page!</h1>
</body>
</html>
之後會講解模板的具體用法,現在接著來定義 errors.py:
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
上面的步驟是讓程式的路由儲存在 views.py 中,而錯誤處理交給 errors.py,這兩個模組已經和藍本 main 關聯起來了(在藍本中匯入了這兩個模組),現在需要在工廠函式中註冊藍本 main。將如下程式碼加入到上面預設程式碼中即可:
app/__init__.py
def create_app(config_name):
#...
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
最後兩個步驟是建立 requirements.txt 以及啟動指令碼 manage.py。程式中必須包含一個 requirements.txt 檔案,用於記錄所有的依賴包和版本號,便於在其它電腦上建立相同的開發環境。直接在終端使用如下命令即可建立 requirements.txt 檔案:
pip freeze > requirements.txt
以後安裝了新的依賴包或者升級版本後,重新執行該命令即可更新 requirements.txt 檔案。如果要手動新增也可以,在 PyCharm 中用 Command + , 喚出 Preferences 對話方塊,然後選擇 Project -> Project Interpreter 即可檢視所有的依賴包及其版本號(還有最新版本號提示),如圖:
如果要在另一臺電腦上建立這個虛擬環境的完全副本,執行以下命令即可:
pip install -r requirements.txt
最後建立啟動指令碼 manage.py:
manage.py
import os
from app import create_app, db
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
return dict(app=app, db=db)
manager.add_command("shell",Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
這個指令碼首先建立程式,然後增加了兩個命令:shell 和 db,我們之後可以在命令列中直接使用。
到此為止,我們的目錄結構如下:
執行
現在就來啟動我們的程式,在命令列中進入 TestProject 目錄,然後執行如下命令即可執行:
python manage.py runserver
命令列執行截圖如下:
Flask 預設的本機地址為:http://127.0.0.1:5000/ ,現在用瀏覽器開啟這個地址,應該可以看到如下頁面:
到這一步,我們的第一個 Flask 程式已經完成了!雖然還沒有建立資料庫,頁面也非常糟糕,但是之後我們會一步步進行完善!
本文參考書籍 Flask Web 開發:基於 Python 的 Web 應用開發實戰(作者: Miguel Grinberg)
相關文章
- 如何從零開始寫一個網站網站
- 從零開始開發一個大型網站網站
- 從零開始搭建一個 hexo 部落格。Hexo
- 從零開始搭建一個vue專案Vue
- 從零開始搭建一個mock服務Mock
- 從零開始搭建React應用(一)——基礎搭建React
- 從零開始寫一個網頁網頁
- 從零開始搭建一個舒適的ubuntuUbuntu
- 從零開始 如何打造一個誘人的電商網站網站
- 從零開始搭建屬於自己的網站網站
- 從零開始:用REACT寫一個格鬥遊戲(一)React遊戲
- 從零開始寫一個ExporterExport
- 從零開始開發一個 WebpackWeb
- 從零開始搭建webpack應用Web
- 從零開始:用REACT寫一個格鬥遊戲(二)React遊戲
- 從零開始搭建一個 Webpack 開發環境配置(附 Demo)Web開發環境
- 從零開始仿寫一個抖音App——開始APP
- 從零開始搭建一個 React + Mobx + React Router 腳手架React
- 【從零開始擼一個App】PKCEAPP
- 從零開始寫一個node爬蟲(一)爬蟲
- 從零開始做一個SLG遊戲(一):六邊形網格遊戲
- 從零開始用 electron 手擼一個截圖工具
- 從零開始實現一個RPC框架(零)RPC框架
- 從零開始實現一個RPC框架(一)RPC框架
- 【從零開始擼一個App】KotlinAPPKotlin
- 如何從零開始學習一個框架框架
- 從零開始搭建 gRPC 服務 – Golang 篇(一)RPCGolang
- 「基礎搭建」從零開始,基於 Webpack5 搭建一個 Vue-CliWebVue
- 從零開始做一個SLG遊戲(四):UI系統之主介面搭建遊戲UI
- 從零開始搭建一個安全的登入表單網站:步驟詳解與最佳實踐,表單系統搭建網站
- 從零開始完成一個Android JNI開發Android
- 從零開始構建一個webpack專案Web
- 從零開始編寫一個babel外掛Babel
- 從零開始擼一個Fresco之總結
- 從零開始一個微信小程式版知乎微信小程式
- 從零開始寫一個Javascript解析器JavaScript
- 從零開始構建react應用(一)前言React
- 從零開始開發一個Node互動式命令列應用命令列