flask 在模板中渲染表單 --


在模板中渲染表單

為了能夠在模板中渲染表單,我們需要把表單類實例傳入模板。首先在視圖函數里實例化表單類LoginForm,然后再render_template()函數中使用關鍵腦子參數form將表單實例傳入模板,例如:form/app.py

#傳入表單類實例
from forms import LoginForm

@app.route('/basic')
def basic():
    form=LoginForm()
    return render_template('login.html',form=form)

 

 

在模板中,需要調用表單類的屬性即可獲取字段對應的HTML代碼,如果需要傳入參數,也可以添加括號,如form/templates/basic.html:在模板中渲染表單

<form method="post">

    {{ form.csrf_token }}<!-- 渲染CSRF令牌隱藏字段 -->

    {{ form.username.label }}{{ form.username }}<br>

    {{ form.password.label }}{{ form.password }}<br>

    {{ form.remember }}{{ form.remember.label }}<br>

    {{ form.submit }}<br>

</form>

 

在上面的代碼中,除了渲染各個字段的標簽和字段本身,還調用了form.csrf_token屬性渲染Flask-WTF為表單類自動創建的CSRF令牌字段。form.csrf_token字段包含了自動生成的CSRF令牌值,在提交表單后會自動被驗證,為了確保表單通過驗證,我們必須在表單中手動渲染這個字段。

 

Flask_WTF為表單類實例提供了一個form.hidden_tag()方法,這個方法會依次渲染表單中所有的隱藏字段。因為csrf_token字段也是隱藏字段,所有當這個方法被調用時也會渲染csrf_token字段。

渲染后獲得的實際HTML代碼如下:

<form method="post">
    <input id="csrf_token" name="csrf_token" type="hidden" value="ImE1M2QxNDEyNDA2YTE5NGI3NmU1NGY1M2U2ZDkxNjQ2NDc5NTI3ZjYi.XH0xaQ.RvNFnjwMfAiUyiv58pU2xJkQ42g"><!-- 渲染CSRF令牌隱藏字段 -->
    <label for="username">Username</label><input id="username" name="username" required type="text" value=""><br>
    <label for="password">Password</label><input id="password" name="password" required type="password" value=""><br>
    <input id="remember" name="remember" type="checkbox" value="y"><label for="remember">Remember me</label><br>
    <input id="submit" name="submit" type="submit" value="Log in"><br>
</form>

 

運行該程序,訪問127.0.0.1:5000/basic可以看到渲染后的表單,頁面中的表單和我們在上面使用HTML編寫的表單相同

在前面介紹過,使用render_kw字典或是在調用字段時傳入參數來定義字段的額外HTML屬性,可以通過這種方式添加CSS類,我們編寫一個Bootstrap風格的表單:

form/templates/bootstrap.html

{% extends 'base.html' %}
{% block styles %}
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
{% endblock %}
{% block content %}
    <h1 class="display-4">Bootstrap Style Form</h1>
    <form method="post">
        {{ form.csrf_token }}
        <div class="form-group">
            {{ form.username.label }}
            {{ form.username(class='form-control') }}
        </div>
        <div class="form-group">
            {{ form.password.label }}
            {{ form.password(class='form-contrl') }}
        </div>
        <div class="form-check">
            {{ form.remember(class='form-check-input') }}
            {{ form.remember.label }}
        </div>
        {{ form.submit(class='btn btn-primary') }}
    <form/>
{% endblock content %}

 

頁面上訪問127.0.0.1:5000/bootstrap

 

base.html:

<!DOCTYPE html>
<html lang="en">
<head>
    {% block head %}
        {% block metas %}
            <meta charset="utf-8">
        {% endblock metas %}
        <title>
            {% block title %}
                Form - HelloFlask
            {% endblock title %}
        </title>
        <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='favicon.ico') }}">
        {% block styles %}
            <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
        {% endblock styles %}
    {% endblock head %}
</head>
<body>
<nav>
    {% block nav %}
        <ul>
            <li><a href="{{ url_for('basic') }}">Home</a></li>
        </ul>
    {% endblock %}
</nav>

<main>
    {% for message in get_flashed_messages() %}
        <div class="alert">
            {{ message }}
        </div>
    {% endfor %}
    {% block content %}{% endblock %}
</main>
<footer>
    {% block footer %}
        <small> &copy; 2019 <a href="https://www.cnblogs.com/xiaxiaoxu/" title="xiaxiaoxu's blog">夏曉旭的博客</a> /
            <a href="https://github.com/xiaxiaoxu/hybridDrivenTestFramework" title="Contact me on GitHub">GitHub</a> /
            <a href="http://helloflask.com" title="A HelloFlask project">Learning from GreyLi's HelloFlask</a>
        </small>
    {% endblock %}
</footer>
{% block scripts %}{% endblock %}
</body>
</html>

 

style.css文件:

body{
    margin:auto;
    width:750px;
}

img{
    max-width:710px;
}

nav ul{
    list-style-type:none;
    margin:0;
    padding:0;
    overflow:hidden;
    background-color:#333;
}

nav li{
    float:left;
}

nav li.a{
    display:block;
    color:white;
    text-align:center;
    padding:14px 16px;
    text-decoration:none;
}

h1{
    color:red;
    text-align:center;
    padding:14px 16px;
    text-decoration:none;
}


label{width:200px;display:inline-block;}


nav li a:hover{
    background-color:#111;
}

main{
    padding:10px 20px;
}

footer{
    font-size:13px;
    color:#888;
    border-top:1px solid #666;
    margin-top:25px;
    text-align:center;
    padding:10px;
}

.alert{
    position:relative;
    padding:0.75rem 1.25rem;
    margin-bottom:1rem;
    border:1px solid #b8daff;
    border-radius:0.25rem;
    color:#004085;
    background-color: #cce5ff;
}

.error{
    color:red;
}
 

app.py:

#encoding=utf-8
from flask import Flask,render_template,flash,redirect,url_for,session
import os

app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY','secret string')

@app.route('/html',methods=['GET','POST'])
def html():
    return render_template('pure_html.html')

from forms import LoginForm
#傳入表單類實例


@app.route('/basic')
def basic():
    form=LoginForm()
    return render_template('basic.html',form=form)

@app.route('/bootstrap',methods=['GET','POST'])
def bootstrap():
    form = LoginForm()
    if form.validate_on_submit():
        username = form.username.data
        flash('welcome home,%s!'% username)
        return redirect(url_for('basic'))
    return render_template('bootstrap.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

 

 

forms.py:

#encoding=utf-8
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Length

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)])
    remember = BooleanField('Remember me')
    submit = SubmitField('Log in')

from flask import Flask,render_template,flash,redirect,url_for,session
import os

app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY','secret string')




if __name__ == '__main__':
    app.run(debug=True)
如果想手動編寫HTML表單的代碼,需要注意表單字段的name屬性值必須和表單類的字段名稱相同,這樣在提交表單時WTForms才能正確地獲取數據並進行驗證。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM