FlaskForm詳解

FlaskForm,是Flask框架中的一個表單處理擴展,它可以幫我們更方便地管理表單,實現表單驗證、提交等功能,減輕了我們的工作壓力。本文從多個方面對FlaskForm做詳細的闡述,以便讀者更好地理解與使用它。

一、FlaskForm二級聯動

在我們的Web應用中,常常需要進行二級聯動功能的實現,比如省、市、區的地址選擇,或者是商品類型、子類的選擇等等。使用FlaskForm可以很方便地實現這樣的功能。

首先我們需要定義表單類,下面是一個例子:

from wtforms import SelectField, Form, validators
 
choices_a = [("", "請選擇..."), ("1", "選項1"), ("2", "選項2"), ("3", "選項3"), ("4", "選項4")]
choices_b = [("", "請選擇..."), ("a", "選項A"), ("b", "選項B"), ("c", "選項C"), ("d", "選項D")]
 
class TestForm(Form):
    select_a = SelectField("級別1", choices=choices_a, validators=[validators.DataRequired()])
    select_b = SelectField("級別2", choices=choices_b, validators=[validators.DataRequired()])

接下來,我們需要在視圖函數中使用這個表單類。在GET請求中,我們需要傳遞一個空的表單實例到前端,讓用戶進行選擇;在POST請求中,我們需要對用戶選擇的數據進行處理並返回結果。

from flask import render_template, request
 
@app.route("/double_select", methods=["GET", "POST"])
def double_select():
    form = TestForm(request.form)
 
    if request.method == "POST" and form.validate():
        select_a = form.select_a.data
        select_b = form.select_b.data
 
        # 處理選項數據...
 
        return "success"
 
    return render_template("double_select.html", form=form)

在前端模板中,我們需要利用FlaskForm提供的表單插件來渲染二級聯動的功能。下面是一個例子:

<form method="post" action="">
    {{ form.select_a.label }} {{ form.select_a }}
    {{ form.select_b.label }} {{ form.select_b }}
    <input type="submit" value="提交">
</form>
{{ form.hidden_tag() }}
 
...
 
<script>
$(function() {
    $("#select_a").on("change", function() {
        $.get("/get_select_b", {"select_a": $(this).val()}, function(data) {
            var optionsHtml = "";
            $.each(data, function(key, value) {
                optionsHtml += "<option value='" + key + "'>" + value + "</option>";
            });
            $("#select_b").html(optionsHtml);
        }, "json");
    });
});
</script>

在這個例子中,我們使用了flask_wtf插件來渲染表單,使用了jQuery庫來實現異步加載子類選項數據的功能。

二、FlaskForm CSRF

在我們的Web應用中,跨站請求偽造(CSRF)是一種常見的安全漏洞,攻擊者可以通過構造惡意請求來實現用戶信息、資金等的竊取或者篡改。使用FlaskForm提供的CSRF保護可以很好地防禦這種安全漏洞。

在Flask中,我們可以通過在FlaskForm實例中設置SECRET_KEY來啟用CSRF保護。下面是一個例子:

from flask_wtf.csrf import CSRFProtect
 
app = Flask(__name__)
app.config["SECRET_KEY"] = "your-secret-key"
csrf = CSRFProtect(app)

這裡我們設置了一個隨機的SECRET_KEY,用來加密和驗證TOKEN,保證應用的安全性。然後我們使用CSRFProtect包裝我們的Flask應用來啟用CSRF保護。

啟用CSRF保護後,我們需要在前端模板中使用FlaskForm提供的表單插件來渲染form標籤,其中包含了_csrf_token的隱藏字段。下面是一個例子:

<form method="post" action="">
    {{ form.username.label }} {{ form.username }}
    {{ form.password.label }} {{ form.password }}
    <input type="submit" value="提交">
</form>
{{ form.hidden_tag() }}

當我們在POST請求中提交表單數據時,FlaskForm會自動從表單數據中獲取_csrf_token字段,並且與其中包含的加密簽名進行比較驗證,如果驗證失敗則拋出異常。

三、FlaskForm聯合查詢

在我們的Web應用中,常常需要實現複雜的聯合查詢功能,比如商品名稱、類型、價格的多條件組合查詢等等。使用FlaskForm可以很方便地實現這樣的功能。

FlaskForm提供了各種表單字段類型來方便我們實現多條件查詢,比如StringField、SelectField、DateField等。下面是一個例子:

from flask_wtf import FlaskForm
from wtforms import StringField, SelectField, DateField
from wtforms.validators import DataRequired
 
class QueryForm(FlaskForm):
    name = StringField("名稱")
    category = SelectField("分類", choices=[("all", "全部"), ("1", "分類1"), ("2", "分類2")])
    price_min = StringField("最小价格")
    price_max = StringField("最大價格")
    create_time = DateField("創建日期", format="%Y-%m-%d")
    update_time = DateField("更新日期", format="%Y-%m-%d")

在視圖函數中,我們使用這個表單類來接收並且處理用戶提交的查詢條件。下面是一個例子:

@app.route("/query", methods=["GET", "POST"])
def query():
    form = QueryForm(request.form)
 
    if request.method == "POST" and form.validate():
        name = form.name.data.strip() or None
        category = form.category.data
        if category == "all":
            category = None
 
        try:
            price_min = float(form.price_min.data.strip())
        except:
            price_min = None
 
        try:
            price_max = float(form.price_max.data.strip())
        except:
            price_max = None
 
        create_time = form.create_time.data or None
        update_time = form.update_time.data or None
 
        # 處理查詢條件...
 
        return "success"
 
    return render_template("query.html", form=form)

在前端模板中,我們可以使用FlaskForm提供的表單插件來渲染表單。下面是一個例子:

<form method="post" action="">
    {{ form.name.label }} {{ form.name }}
    {{ form.category.label }} {{ form.category }}
    {{ form.price_min.label }} {{ form.price_min }}
    {{ form.price_max.label }} {{ form.price_max }}
    {{ form.create_time.label }} {{ form.create_time }}
    {{ form.update_time.label }} {{ form.update_time }}
    <input type="submit" value="查詢">
</form>
{{ form.hidden_tag() }}

四、FlaskForm CSRF取消

在某些情況下,我們可能需要在特定表單中取消FlaskForm的CSRF保護,比如在我們需要讓用戶在不登錄的情況下進行某些操作的時候。FlaskForm提供了一個@csrf_exempt裝飾器來完成這個功能。

在視圖函數中,我們只需要在函數上方加上@csrf_exempt裝飾器即可取消FlaskForm的CSRF保護。下面是一個例子:

from flask_wtf.csrf import csrf_exempt
 
@app.route("/some_action", methods=["POST"])
@csrf_exempt
def some_action():
    # 處理不需要CSRF保護的操作...
    return "success"

五、FlaskForm Python三級聯動

除了常見的二級聯動,有些特定的業務場景可能需要實現三級或者更多級聯動的功能。FlaskForm同樣可以很方便地實現這些功能。

在實現三級聯動的時候,我們需要使用三個FlaskForm實例來分別表示三個下拉框。下面是一個例子:

from wtforms import Form, SelectField
 
class SelectAForm(Form):
    select_a = SelectField("級別1")
 
class SelectBForm(Form):
    select_b = SelectField("級別2")
 
class SelectCForm(Form):
    select_c = SelectField("級別3")

然後我們需要在視圖函數中使用這三個表單來實現三級聯動。在GET請求中,我們需要傳遞一族空表單到前端;在POST請求中,我們需要處理用戶的選擇,並且動態返回下一級的選項。下面是一個例子:

@app.route('/three_levels')
def three_levels():
    select_a_form = SelectAForm()
    select_b_form = SelectBForm()
    select_c_form = SelectCForm()
 
    return render_template("three_levels.html", select_a_form=select_a_form, select_b_form=select_b_form, select_c_form=select_c_form)
 
@app.route("/get_b")
def get_b():
    select_b_form = SelectBForm()
    id = request.args.get("id", 0, type=int)
 
    if id == 1:
        select_b_form.select_b.choices = [("", "選擇..."), (1, "選項1"), (2, "選項2"), (3, "選項3")]
    elif id == 2:
        select_b_form.select_b.choices = [("", "選擇..."), (4, "選項4"), (5, "選項5"), (6, "選項6")]
    elif id == 3:
        select_b_form.select_b.choices = [("", "選擇..."), (7, "選項7"), (8, "選項8"), (9, "選項9")]
 
    return jsonify(select_b_form.select_b.choices)
 
@app.route("/get_c")
def get_c():
    select_c_form = SelectCForm()
    id = request.args.get("id", 0, type=int)
 
    if id == 1:
        select_c_form.select_c.choices = [("", "選擇..."), (1, "選項1"), (2, "選項2"), (3, "選項3")]
    elif id == 2:
        select_c_form.select_c.choices = [("", "選擇..."), (4, "選項4"), (5, "選項5"), (6, "選項6")]
    elif id == 3:
        select_c_form.select_c.choices = [("", "選擇..."), (7, "選項7"), (8, "選項8"), (9, "選項9")]
 
    return jsonify(select_c_form.select_c.choices)

在前端模板中,我們需要利用FlaskForm提供的表單插件來渲染三個下拉框。其中第一級會觸發AJAX請求,返回第二級的選項;第二級會觸發AJAX請求,返回第三級的選項。下面是一個例子:

<form>
{{ select_a_form.select_a.label }} {{ select_a_form.select_a }}
{{ select_b_form.select_b.label }} {{ select_b_form.select_b }}
{{ select_c_form.select_c.label }} {{ select_c_form.select_c }}
</form>

<script>
$(function() {
$("#select_a").on("change", function() {
var id = $(this).val();
if (id) {
$.get("/get_b", {"id": id}, function(data) {
var optionsHtml = "<option value=''>-</option>";
$.each(data, function(key, value) {
optionsHtml += "<option value='" + key + "'>" + value + "</option>";
});
$("#select_b").html(optionsHtml).change();
}, "json");
} else {
$("#select_b").html("<option value=''>-</option>");
$("#select_c").html("<option value=''>-</option>");
}
});

原創文章,作者:ZQSQ,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/138098.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ZQSQ的頭像ZQSQ
上一篇 2024-10-04 00:18
下一篇 2024-10-04 00:19

相關推薦

  • 神經網絡代碼詳解

    神經網絡作為一種人工智能技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網絡的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網絡模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁盤中。在執行sync之前,所有的文件系統更新將不會立即寫入磁盤,而是先緩存在內存…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變量讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • C語言貪吃蛇詳解

    一、數據結構和算法 C語言貪吃蛇主要運用了以下數據結構和算法: 1. 鏈表 typedef struct body { int x; int y; struct body *nex…

    編程 2025-04-25
  • MPU6050工作原理詳解

    一、什麼是MPU6050 MPU6050是一種六軸慣性傳感器,能夠同時測量加速度和角速度。它由三個傳感器組成:一個三軸加速度計和一個三軸陀螺儀。這個組合提供了非常精細的姿態解算,其…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web服務器。nginx是一個高性能的反向代理web服務器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25

發表回復

登錄後才能評論