欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Python Flask框架的安裝及應(yīng)用

 更新時間:2022年05月31日 09:46:54   作者:beautifulzzzz  
Flask誕生于愚人節(jié)開的一個玩笑,后來逐漸發(fā)展成為一個成熟的 Python Web框架,越來越受到開發(fā)者的喜愛。本文將以一個博客后臺為例,詳解Flask框架的安裝及應(yīng)用,需要的可以參考一下

1.安裝

1.1 創(chuàng)建虛擬環(huán)境

mkdir myproject
cd myproject
python3 -m venv venv

1.2 進入虛擬環(huán)境

. venv/bin/activate

1.3 安裝 flask

pip install Flask

2.上手

2.1 最小 Demo

將下列代碼保存為 hello.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

運行上述代碼:

export FLASK_APP=hello
flask run

這樣訪問:http://127.0.0.1:5000 會看到 Hello, World!

2.2 基本知識

這里有 flask 的基本知識(非常重要的基礎(chǔ),大家可以自己看:鏈接

1.HTML Escaping (利用 Jinja,參考:鏈接

2.Routing (下面幾個例子)

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

@app.route('/hello')
def hello():
    return 'Hello, World'

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return f'User {escape(username)}'

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return f'Post {post_id}'

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return f'Subpath {escape(subpath)}'

3.HTTP Methods

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
    else:

4.Static Files (url_for('static', filename='style.css'))

5.Rendering Templates (這個參考之前的 Jinja)

6.File Uploads、Cookies、Redirects and Errors、About Responses、APIs with JSON、Sessions、Message Flashing、Logging 這些等我們實際用到時再過來看

3.解構(gòu)官網(wǎng)指導(dǎo) Demo

第 1 節(jié)教大家如何利用 python 虛擬環(huán)境,快速構(gòu)建 flask 環(huán)境;第 2 節(jié)帶著大家簡單熟悉了 flask 的編程規(guī)則(或風(fēng)格)。

大家在著手本節(jié)時,務(wù)必將第 2 節(jié)中的基礎(chǔ)的代碼跟著官網(wǎng)敲一下!因為,這一節(jié)我們不是由簡到難一步步搭建 flask 服務(wù)器,而是直接拿搭建好的反過來分析。

3.1 克隆與代碼架構(gòu)分析

$ git clone https://github.com/pallets/flask
$ cd flask
$ cd examples/tutorial

代碼目錄結(jié)構(gòu)如下:

3.2 入口文件 init.py

def create_app(test_config=None):
    """Create and configure an instance of the Flask application."""
    # 1-創(chuàng)建一個 Flask 實例
    # 并設(shè)置一些 APP 需要用到的參數(shù)
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_mapping(
        # a default secret that should be overridden by instance config
        SECRET_KEY="dev",
        # store the database in the instance folder
        DATABASE=os.path.join(app.instance_path, "flaskr.sqlite"),
    )

	# 2-測試用的
    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile("config.py", silent=True)
    else:
        # load the test config if passed in
        app.config.update(test_config)

	# 3-創(chuàng)建一個文件夾,用來存 DB 運行時的產(chǎn)生的文件
    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    @app.route("/hello")
    def hello():
        return "Hello, World!"

    # register the database commands
    # 3.3 數(shù)據(jù)庫設(shè)置(為 flask 新增一個 init_db 命令,這樣直接敲 flask init_db 就能生成表)
    from flaskr import db

    db.init_app(app)

    # apply the blueprints to the app
    # #### 3.4 藍圖和視圖(基于藍圖來管理組織視圖,視圖注冊到藍圖,藍圖注冊到應(yīng)用)
    from flaskr import auth, blog

    app.register_blueprint(auth.bp)
    app.register_blueprint(blog.bp)

    # make url_for('index') == url_for('blog.index')
    # in another app, you might define a separate main index here with
    # app.route, while giving the blog blueprint a url_prefix, but for
    # the tutorial the blog will be the main index
    app.add_url_rule("/", endpoint="index")

    return app

3.3 數(shù)據(jù)庫設(shè)置

該項目采用了 SQLite 作為數(shù)據(jù)庫(Python 內(nèi)置了,免去安裝和配置工作)。

1.SQL 文件 schema.sql

SQLite 的數(shù)據(jù)存儲在表格中,在向表格增刪改查數(shù)據(jù)前,需要先建表。該項目中的 schema.sql 編寫了建表的 SQL 語句。分別創(chuàng)建了一個 user 表和 post 表。

DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post;

CREATE TABLE user (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  username TEXT UNIQUE NOT NULL,
  password TEXT NOT NULL
);

CREATE TABLE post (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  author_id INTEGER NOT NULL,
  created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  title TEXT NOT NULL,
  body TEXT NOT NULL,
  FOREIGN KEY (author_id) REFERENCES user (id)
);

2)與數(shù)據(jù)庫建立連接與斷開

def get_db():
    """Connect to the application's configured database. The connection
    is unique for each request and will be reused if this is called
    again.
    """
    if "db" not in g:
        g.db = sqlite3.connect(
            current_app.config["DATABASE"], detect_types=sqlite3.PARSE_DECLTYPES
        )
        g.db.row_factory = sqlite3.Row

    return g.db


def close_db(e=None):
    """If this request connected to the database, close the
    connection.
    """
    db = g.pop("db", None)

    if db is not None:
        db.close()

g 是一個特殊結(jié)構(gòu),對于每次請求,會產(chǎn)生一個。

3)數(shù)據(jù)庫初始化(生成表)

第 1 節(jié)的 schema.sql 用于建表,那么如何執(zhí)行其中的建表命令呢? db.py 中的 init_db 就是干這個事情的。

def init_db():
    """Clear existing data and create new tables."""
    db = get_db()      # 獲取數(shù)據(jù)庫(如果沒有則創(chuàng)建)
    
	# 讀取 schema.sql 中的 SQL 命令,并用 db.executescript 執(zhí)行 SQL 命令
    with current_app.open_resource("schema.sql") as f:
        db.executescript(f.read().decode("utf8"))   

4)將 init_db 注冊為 flask 命令

由于數(shù)據(jù)庫初始化并不需要每次啟動數(shù)據(jù)庫時運行(不屬于運行時需要執(zhí)行的函數(shù)),我們需要將注冊成 flask 一個指令,只要在命令行中敲 flask init-db 就能夠執(zhí)行 init_db,其實現(xiàn)方法如下:

@click.command("init-db")
@with_appcontext
def init_db_command():
    """Clear existing data and create new tables."""
    init_db()
    click.echo("Initialized the database.")
    
def init_app(app):
    """Register database functions with the Flask app. This is called by
    the application factory.
    """
    app.teardown_appcontext(close_db) # 在返回響應(yīng)后進行清理時調(diào)用該函數(shù)
    app.cli.add_command(init_db_command) # 添加一個可以用flask命令調(diào)用的新命令

這樣,執(zhí)行完之后,flask.sqlite 文件將會出現(xiàn)在 instance 文件夾。

3.4 藍圖和視圖

藍圖是一種組織一組相關(guān)視圖和其他代碼的方法。它們不是直接向應(yīng)用程序注冊視圖和其他代碼,而是向藍圖注冊。然后,當(dāng)藍圖在factory函數(shù)中可用時,它將在應(yīng)用程序中注冊。

該項目中有兩個藍圖:auth 和 blog

bp = Blueprint("auth", __name__, url_prefix="/auth")   # in auth.py
bp = Blueprint("blog", __name__) # in blog.py

參數(shù)分別是:藍圖的名字,import_name(一般為 __name__),url 前綴

[1].官方 Demo Github 倉庫

1)auth 視圖

這里主要有三個路由:

@bp.route("/register", methods=("GET", "POST"))
def register():
...

@bp.route("/login", methods=("GET", "POST"))
def login():
...

@bp.route("/logout")
def logout():

2)blog 視圖

這里主要有四個路由:

@bp.route("/")
def index():
...

@bp.route("/create", methods=("GET", "POST"))
@login_required
def create():
...

@bp.route("/<int:id>/update", methods=("GET", "POST"))
@login_required
def update(id):
...

@bp.route("/<int:id>/delete", methods=("POST",))
@login_required
def delete(id):
...

3)注冊視圖中各個功能實現(xiàn)介紹

注冊

注冊邏輯為:首先從 POST 中獲取 username 和 password,然后調(diào)用數(shù)據(jù)庫插入操作:

  • username = request.form["username"]
  • password = request.form["password"]
  • db.execute("INSERT INTO user (username, password) VALUES (?, ?)", (username, generate_password_hash(password)),)

登錄

登錄邏輯為:首先從 POST 中獲取 username 和 password,然后調(diào)用數(shù)據(jù)庫查詢操作,獲取該用戶的密碼,然后進行密碼匹配:

  • user = db.execute("SELECT * FROM user WHERE username = ?",username,)).fetchone()
  • check_password_hash(user["password"], password)

密碼匹配后,需要創(chuàng)建 session:

if error is None:
    # store the user id in a new session and return to the index
    session.clear()
    session["user_id"] = user["id"]
    return redirect(url_for("index"))

注銷

注銷需要清空 session:

session.clear()

Session

Session 邏輯如下:注冊一個方法,讓其在任何 URL 請求之前執(zhí)行,在其中做 Session 管理:

@bp.before_app_request
def load_logged_in_user():
    user_id = session.get('user_id')

    if user_id is None:
        g.user = None
    else:
        g.user = get_db().execute(
            'SELECT * FROM user WHERE id = ?', (user_id,)
        ).fetchone()

其他 View 使用認證

其他 View 也想使用認證該如何做?在 auth.py 中實現(xiàn) login_required 函數(shù),判斷 user 是否為空,如果為空,則跳轉(zhuǎn)到登錄頁面:

def login_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
    if g.user is None:
        return redirect(url_for('auth.login'))

    return view(**kwargs)

return wrapped_view

4)博客視圖中各個功能實現(xiàn)介紹

展示所有博客

邏輯如下:執(zhí)行數(shù)據(jù)庫查詢操作,獲取所有博客,然后加載:

@bp.route("/")
def index():
    """Show all the posts, most recent first."""
    db = get_db()
    posts = db.execute(
        "SELECT p.id, title, body, created, author_id, username"
        " FROM post p JOIN user u ON p.author_id = u.id"
        " ORDER BY created DESC"
    ).fetchall()
    return render_template("blog/index.html", posts=posts)

創(chuàng)建博客

邏輯如下:函數(shù)前加上 @login_required 前綴,這樣就能自動判斷是否已經(jīng)登錄,否則跳到登錄頁面;創(chuàng)建博客就是獲取標(biāo)題和內(nèi)容,然后調(diào)用插入命令,進行插入:

@bp.route("/create", methods=("GET", "POST"))
@login_required
def create():
    """Create a new post for the current user."""
    if request.method == "POST":
        title = request.form["title"]
        body = request.form["body"]
        error = None

        if not title:
            error = "Title is required."

        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.execute(
                "INSERT INTO post (title, body, author_id) VALUES (?, ?, ?)",
                (title, body, g.user["id"]),
            )
            db.commit()
            return redirect(url_for("blog.index"))

    return render_template("blog/create.html")

更新和刪除博客

更新和刪除博客,需要傳入一個 id,然后有一個內(nèi)部函數(shù)用于判斷該 id 是否存在:

def get_post(id, check_author=True):
    """Get a post and its author by id.

    Checks that the id exists and optionally that the current user is
    the author.

    :param id: id of post to get
    :param check_author: require the current user to be the author
    :return: the post with author information
    :raise 404: if a post with the given id doesn't exist
    :raise 403: if the current user isn't the author
    """
    post = (
        get_db()
        .execute(
            "SELECT p.id, title, body, created, author_id, username"
            " FROM post p JOIN user u ON p.author_id = u.id"
            " WHERE p.id = ?",
            (id,),
        )
        .fetchone()
    )

    if post is None:
        abort(404, f"Post id {id} doesn't exist.")

    if check_author and post["author_id"] != g.user["id"]:
        abort(403)

    return post

因此,更新的邏輯如下:

@bp.route("/<int:id>/update", methods=("GET", "POST"))
@login_required
def update(id):
    """Update a post if the current user is the author."""
    post = get_post(id)

    if request.method == "POST":
        title = request.form["title"]
        body = request.form["body"]
        error = None

        if not title:
            error = "Title is required."

        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.execute(
                "UPDATE post SET title = ?, body = ? WHERE id = ?", (title, body, id)
            )
            db.commit()
            return redirect(url_for("blog.index"))

    return render_template("blog/update.html", post=post)

刪除的邏輯如下:

@bp.route("/<int:id>/delete", methods=("POST",))
@login_required
def delete(id):
    """Delete a post.

    Ensures that the post exists and that the logged in user is the
    author of the post.
    """
    get_post(id)
    db = get_db()
    db.execute("DELETE FROM post WHERE id = ?", (id,))
    db.commit()
    return redirect(url_for("blog.index"))

4.其他

其他還有一些,是大家玩熟了之后才需要看的:

5.跑起 DEMO

最后,我們跑起 Demo 看看效果:

1)在 tutorial 目錄下,創(chuàng)建虛擬環(huán)境,并安裝 Flask:

python3 -m venv venv
. venv/bin/activate
pip install Flask

2)以開發(fā)者方式運行:

export FLASK_APP=flaskr
export FLASK_ENV=development
flask init-db
flask run

效果如下:

以上就是詳解Python Flask框架的安裝及應(yīng)用的詳細內(nèi)容,更多關(guān)于Python Flask框架的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python變量定義的簡單使用介紹

    Python變量定義的簡單使用介紹

    這篇文章主要介紹了Python變量定義的簡單使用介紹,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • PyTorch如何使用embedding對特征向量進行嵌入

    PyTorch如何使用embedding對特征向量進行嵌入

    這篇文章主要介紹了PyTorch如何使用embedding對特征向量進行嵌入問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Python 讀取圖片文件為矩陣和保存矩陣為圖片的方法

    Python 讀取圖片文件為矩陣和保存矩陣為圖片的方法

    下面小編就為大家分享一篇Python 讀取圖片文件為矩陣和保存矩陣為圖片的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Pycharm plot獨立窗口顯示的操作

    Pycharm plot獨立窗口顯示的操作

    這篇文章主要介紹了Pycharm plot獨立窗口顯示的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Python實現(xiàn)批量檢測HTTP服務(wù)的狀態(tài)

    Python實現(xiàn)批量檢測HTTP服務(wù)的狀態(tài)

    本文給大家分享的是一個使用python實現(xiàn)的批量檢測web服務(wù)可用性的腳本代碼,主要功能有測試一組url的可用性(可以包括HTTP狀態(tài)、響應(yīng)時間等)并統(tǒng)計出現(xiàn)不可用情況的次數(shù)和頻率等。
    2016-10-10
  • Python實現(xiàn)名片管理系統(tǒng)

    Python實現(xiàn)名片管理系統(tǒng)

    這篇文章主要為大家詳細介紹了Python實現(xiàn)名片管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 使用Python編寫一個簡單的tic-tac-toe游戲的教程

    使用Python編寫一個簡單的tic-tac-toe游戲的教程

    這篇文章主要介紹了使用Python編寫一個簡單的tic-tac-toe游戲的教程,有利于Python初學(xué)者進行上手實踐,需要的朋友可以參考下
    2015-04-04
  • python各種excel寫入方式的速度對比

    python各種excel寫入方式的速度對比

    這篇文章主要介紹了python各種excel寫入方式的速度對比,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Python?實操顯示數(shù)據(jù)圖表并固定時間長度

    Python?實操顯示數(shù)據(jù)圖表并固定時間長度

    這篇文章主要介紹了Python?實操顯示數(shù)據(jù)圖表并固定時間長度,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • Python中的裝飾器使用

    Python中的裝飾器使用

    這篇文章主要介紹了Python中的裝飾器使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評論