python中Flask Web 表單的使用方法介紹

簡介

表單的操作是Web程序開發中最核心的模塊之一,絕大多數的動態交互功能都是通過表單的形式實現的。本文會教大傢實現簡單的表單操作。

普通表單提交

在創建模板login.html頁面中直接寫form表單。

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="" method="post">
        <input type="text" name="username" placeholder="Username">
        <input type="password" name="password" placeholder="Password">
        <input type="submit" value="提交">
    </form>
    {% if method == 'GET' %}
        請求方式:{{method}}
    {% elif method == 'POST' %}
        請求方式:{{method}}
        用戶名:{{ username }}
        密碼:{{ password }}
    {% endif %}
    
</body>
</html>

接下來,在視圖函數中獲取表單數據

login.py

from flask import Flask, render_template, request​
app = Flask(__name__)​
# index 視圖函數
@app.route('/login', methods=['GET', 'POST'])
def login():
    context = dict()​
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        print(username, password)
        context = {
            'username': username,
            'password': password,
        }
        context.update({'method': request.method})
    else:
        context.update({'method': request.method})
    return render_template('login.html', **context)
@app.route('/')
def index():
    return 'hello'
if __name__ == '__main__':
    app.run(debug=True)

當我們點擊提交之後,則會顯示:

上面的實現方式是直接采用表單的提交方式。但是有個弊端,假如參數很多的情況下,後臺也需要一一進行驗證,每次都是先接收參數,再對參數進行校驗的話,工作量就會非常的龐大,而且還會出現csrf攻擊,這時我們就可以采用Flask-WTF來創建表單,從而避免上述弊端。

Flask-WTF基礎

Flask-WTF的主要作用是對用戶的請求數據進行驗證。我們可以使用pip命令安裝該依賴,

pip install flask-wtf

在flask web程序中,因為類FlaskForm由Flask-WTF拓展定義,所以可以從flask.wtf中導入FlaskForm。而字段和函數可以直接從WTForms包中導入,WTForms包中可以支持如下所示的HTML標準字段。

字段 說明
StringField 表示文本字段
TextAreaField 表示多行文本字段
PasswordField 表示密碼文本字段
HiddenField 表示隱藏文本字段
DateField 表示日期的文本字段
DateTimeFiled 表示時間的文本字段
IntegerFiled 表示整數類型的文本字段
DecimalField 表示Decimal類型的文本字段
FloatFiled 表示Float類型的文本字段
RadioFiled 表示單選框字段
SelectFiled 表示下拉列表字段

WTForm也包含驗證器,它對表單字段進行驗證,非常方便。

字段 說明
DataRequire 檢查輸入的字段是否為空
Email 檢查字段是否符合郵件格式的約定
IPAddress 在輸入字段中驗證IP地址
Length 驗證輸入字段中的字符串長度是否符合給定長度
NumberRange 驗證給定范圍內輸入字段中的文字
URL 驗證是否為合法的URL

使用Flask-WTF處理表單

編寫兩個視圖函數,以及一個form表單類,用於註冊以及跳轉index頁面。

login.py

from flask import Flask, render_template, redirect, url_for, session
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo
app = Flask(__name__)
app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f"​
class RegisterForm(FlaskForm):
    username = StringField(label="用戶名", validators=[DataRequired('用戶名不能為空')])
    password = PasswordField(label="密碼", validators=[DataRequired('密碼不能為空')])
    password_comfirm = PasswordField(label="確認密碼", validators=[DataRequired('密碼不能為空'), EqualTo('password', '兩次密碼不一致')])
    submit = SubmitField(label='提交')​
@app.route('/register', methods=['GET', 'POST'])
def register():
    form  = RegisterForm()
    if form.validate_on_submit():
        uname = form.username.data
        pwd = form.password.data
        pwd_com = form.password_comfirm.data
        print(uname, pwd, pwd_com)
        session['username'] = uname
        return redirect(url_for('index'))
    return render_template('register.html', form=form)
@app.route('/index')
def index():
    username = session.get('username', '')
    return 'hello %s' % username
if __name__ == '__main__':
    app.run(debug=True)

接下來編寫一個html模板文件,用於用戶註冊使用。

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="" method="post">
        {{form.csrf_token}}
        {{form.username.label}}
        <p>{{ form.username }}</p>
        {% for msg in form.username.errors %}
            <p>{{ msg }}</p>
        {% endfor %}
​
        {{form.password.label}}
        <p>{{ form.password }}</p>
        {% for msg in form.password.errors %}
            <p>{{ msg }}</p>
        {% endfor %}
​
        {{form.password_comfirm.label}}
        <p>{{ form.password_comfirm }}</p>
        {% for msg in form.password.errors %}
            <p>{{ msg }}</p>
        {% endfor %}
​
        {{ form.submit }}
    </form>
</body>
</html>

Flask消息閃現

在Flask框架中,方法flash()功能是實現消息閃現提示效果。Flask官方對閃現的解釋是對用戶的請求做出無刷新的響應。類似於Ajax的刷新效果。

舉一個簡單的例子,當用戶通過表單發送完請求之後,假如用戶名或者是密碼輸入錯誤,那麼服務器就會返回錯誤的提示信息,並在表單頁面上顯示。

具體代碼,如下所示:

login.py

from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
app.secret_key = 'random string'
@app.route('/')
def index():
    return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != 'admin' or request.form['password'] != 'admin':
            flash("用戶名或密碼錯誤")
        else:
            flash('登錄成功')
            return redirect(url_for('index'))
    return render_template('login.html')
if __name__ == '__main__':
    app.run(debug=True)

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登錄</title>
</head>
<body>
    <form action="" method="post">
        <p>username</p>
        <input type="text" name="username">
        <p>password</p>
        <input type="password" name="password">
        <input type="submit" value="登錄">
    </form>
    {% for message in get_flashed_messages() %}
        {% if message %}
            {{message}}
        {% endif %}
    {% endfor %}
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    {% with messages = get_flashed_messages() %}
        {% if messages %}
            {% for message in messages %}
                <p>{{ message }}</p>
            {% endfor %}
        {% endif %}
    {% endwith %}
    <h3>welcome</h3>
    <a href="{{url_for('login')}}" rel="external nofollow" >login</a>
</body>
</html>

上面的代碼實現瞭URL的跳轉,我們首先會進入首頁,首頁中包含瞭進入登錄頁面的鏈接。

文件上傳

在Flas Web程序中要實現文件的上傳非常簡單,與傳遞post和get非常的類似。基本流程如下:

  • (1)將在客戶端上傳的文件保存到flask.request.files對象。
  • (2)使用flask.request.files對象獲取上傳上來的文件名和文件對象
  • (3)調用文件對象中的方法save()將文件保存到指定的目錄中。

簡易的文件上傳程序如下所示:

upload.py

from flask import Flask, flash, render_template, request
app = Flask(__name__)
​
@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'GET':
        return render_template('upload.html')
    else:
        file = request.files['file']
        if file:
            file.save(file.name + '.png')
            return '上傳成功'
@app.route('/')
def index():
    return render_template('index.html')
if __name__ == '__main__':
    app.run(debug=True)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>文件上傳首頁</h1>
    <a href="{{url_for('upload')}}" rel="external nofollow" >文件上傳</a>
</body>
</html>

upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上傳</title>
</head>
<body>
    <form action="" method="post" enctype="multipart/form-data">
​
        <input type="file" name="file">
        <input type="submit" value="點擊我上傳">
    </form>
</body>
</html>

本程序需要點擊跳轉之後才能進入文件上傳頁面,這樣寫的目的隻是因為我比較懶,不想再瀏覽器中輸入一大串的url。

目前上述程序僅僅可以上傳圖片!

文件上傳的另一種寫法

在Flask中上傳文件的步驟非常簡單,首先需要一個HTML表單,將enctype屬性設置為"multipart/form-data"即可。URL處理程序會從request.file[]對象中提取文件,並將它保存到所需要的位置上。

每個上傳的文件首先會保存到服務器上的臨時位置,然後將其保存到最終的實際位置。建議使用secure_filename函數獲取。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="/uploader" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="提交">
    </form>
</body>
</html>

upload.py

from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
app.config['UPLOAD_FLODER']= 'upload/' # 設置文件保存的路徑
@app.route('/')
def upload_file():
    return render_template('upload.html')
@app.route('/uploader', methods=['GET', 'POST'])
def uploader():
    if request.method == 'POST':
        f = request.files['file']
        print(request.files)
        f.save(os.path.join(app.config['UPLOAD_FLODER'], secure_filename(f.filename)))
        return '上傳成功'
    else:
        render_template('upload.html')
if __name__ == '__main__':
    app.run(debug=True)

到此這篇關於python中Flask Web 表單的使用方法介紹的文章就介紹到這瞭,更多相關Java Flask 表單內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: