1. 程式人生 > >Flask模板表單

Flask模板表單

模板表單

flask-bootstrap

安裝:

sudo pip3 install flask-bootstrap

使用

manage.py

from flask_bootstrap import Bootstrap

bootstrap = Bootstrap(app)

自定義base基礎模板

{% extends 'bootstrap/base.html' %}
{% block title %}
    首頁
{% endblock %}
{% block navbar %}
    <nav class="navbar navbar-inverse" style="border-radius: 0;">
        <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                        data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#"><span class="glyphicon glyphicon-eye-open"
                                                       aria-hidden="true"></span></a>
            </div>
​
            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="#">首頁<span class="sr-only">(current)</span></a></li>
                    <li><a href="#">發表部落格</a></li>
                    <li><a href="#">我收藏的</a></li>
                </ul>
​
                <ul class="nav navbar-nav navbar-right">
                    <form class="navbar-form navbar-left">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="Search">
                        </div>
                        <button type="submit" class="btn btn-default">搜尋</button>
                    </form>
                    <li><a href="#">註冊</a></li>
                    <li><a href="#">登入</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">個人中心<span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#">個人資訊</a></li>
                            <li><a href="#">修改頭像</a></li>
                            <li><a href="#">修改密碼</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">修改郵箱</a></li>
                        </ul>
                    </li>
                </ul>
            </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
    </nav>
{% endblock %}
{% block content %}
    <div class="container">
      {% block page_content %}
​
      {% endblock %}
    </div>
{% endblock %}

使用自定義的base模板

{% extends'common/base.html' %}

載入靜態資源

css、js、img、視訊、音訊

建立靜態資原始檔的目錄 static

目錄結構

  project/
    static/
    templates/
    manage.py

例項

{% extends'common/base.html' %}
{% block page_content %}
    <img src="{{ url_for('static',filename='img/meinv.jpg',_external=True) }}" alt="">
{% endblock %}
_external引數 將當期路由地址變成絕對路徑的路由地址
{#
name  公有變數
_name 受保護變數
__name 私有變數 
注意: 在不同的python直譯器中 解釋是不同的 從當前模組中 匯入到其它模組使用 _ 和 __ 是不能匯入(只能在當前檔案中執行)
#}

注意:

如果載入的靜態資原始檔 在static的頂級目錄 則filename=檔名稱 如果包含在某個目錄中 則filename='目錄名/檔名'

在檢視中傳遞多個引數到模板中

1、使用關鍵字方式

@app.route('/')
def index():
    return render_template('index.html',title='標題',con='首頁')

2、使用字典

@app.route('/')
def index():
    return render_template('index.html',data=data{'title':'標題','con':'首頁'})

3、 使用**

@app.route('/')
def index():
    return render_template('index.html',**{'title':'標題','con':'首頁'})

4、 使用 **locals()

@app.route('/')
def index():    
name = 'zhangsan'    
age = 18    
# print(locals()) #返回當前的所有區域性變數 以字典的形式     
return render_template('index.html',**locals())

5、使用全域性變數g

@app.route('/')
def index():
    g.name = 'zhangsan'
    g.age = 18
    return render_template('index.html')
使用:
g.name
g.age

表單

1、 原生表單

form.html

<form action="{{ url_for('check_login') }}" method="post">
    <p>使用者名稱: <input type="text" maxlength="12" name="username" placeholder="請輸入使用者名稱..."></p>
    <p>密碼: <input type="password" name="userpass" placeholder="請輸入密碼..."></p>
    <p><input type="submit" value="登入"></p>
</form>

manage.py中的檢視函式

#表單第一種 原生form
@app.route('/login/')
def login():
    return render_template('yuanshengform/form.html')
​
#獲取表單提交過來的資料
@app.route('/check_login/',methods=['POST']) #設定當前的路由地址只允許post請求
# @app.route('/check_login/') #設定當前的路由地址只允許post請求
def check_login():
    # print(request.form) #獲取不到get傳遞過來的資料
    # print(request.args) #獲取get傳遞過來的資料
    # print(request.form) #獲取不到get傳遞過來的資料
    username = request.form.get('username')
    userpass = request.form.get('userpass')
    return '歡迎{} 密碼為{}'.format(username,userpass)
    # return '獲取到資料了'

倆個合併為同一個

#倆個檢視合併為同一個檢視
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST' and request.form.get('username') and request.form.get('userpass'):
        print(request.form)
        return '資料提交過來'
    return render_template('yuanshengform/form.html')

2、 flask-wtf 表單擴充套件庫

安裝:

sudo pip3 install flask-wtf

說明

     是一個用於表單處理的擴充套件庫 提供了csrf 和表單驗證等功能

欄位型別

欄位名稱 欄位說明
StringField 普通文字欄位
SubmitField 提交欄位
PasswordField 密碼欄位
HiddenField 隱藏域
TextAreaField 多行文字域欄位
DateField 日期欄位
DateTimeField 日期時間欄位
IntegerField 整形欄位
FloatField 浮點形欄位
BooleanField bool欄位
RadioFIeld 單選
SelectField 下拉欄位
FileField 檔案上傳

驗證器

驗證器 驗證器說明
DataRequired 必填
Length 長度 min max
IPAddress ip地址
URL url地址驗證
NumberRange 值的範圍
EqualTo 驗證倆個欄位值的是否相同
Regexp 正則匹配
Email 驗證郵箱

例項

manage.py

from flask import Flask,render_template,request
from flask_script import Manager
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField,SubmitField
from wtforms.validators import DataRequired,Length
​
app = Flask(__name__)
app.config['SECRET_KEY'] = 'abcd' #csrf_token的生成需要使用
bootstrap = Bootstrap(app)
manager = Manager(app)
​
#建立表單類
class Login(FlaskForm):
    #引數1 為label中的內容顯示
    username = StringField('使用者名稱',validators=[DataRequired(message='使用者名稱不能為空'),Length(min=6,max=12,message='使用者名稱在6-12位之間...')])
    userpass = PasswordField('密碼',validators=[DataRequired(message='密碼不能為空'),Length(min=6,max=10,message='密碼長度為6-10位')])
    submit = SubmitField('登入')
​
@app.route('/')
def index():
    return render_template('index.html')
​
@app.route('/login/',methods=['GET','POST'])
def login():
    form = Login() #例項化登入的表單類
    # if request.method=='POST':
    if form.validate_on_submit(): #當前表單的csrf驗證通過 和資料正確 則為真
        # print(request.form) #使用request獲取資料
        print(form.username.data) #使用表單物件獲取資料
        print(form.userpass.data)
        return '表單提交'
    return render_template('flask-wtf-form/form2.html',form=form)
​
​
if __name__ == '__main__':
    manager.run()

form.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>wtf-form</title>
</head>
<body>
<form action="" method="post">
    {{ form.csrf_token }}
    {{ form.username.label() }}
    {{ form.username(placeholder='請輸入使用者名稱...',style='color:red;') }}
{#    {{ form.username.errors }}#}
    {% if form.username.errors %}
        <span style="color: red;">{{ form.username.errors.0 }}</span>
    {% endif %}
    <br>
    {{ form.userpass.label() }}
    {{ form.userpass() }}
{#    {{ form.userpass.errors }}#}
    {% if form.userpass.errors %}
        <span style="color: red;">{{ form.userpass.errors.0 }}</span>
    {% endif %}
    <br>
    {{ form.submit() }}
</form>
</body>
</html>

呼叫封裝成巨集的表單

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .error{
            color: red;
            list-style: none;
        }
    </style>
</head>
<body>
{% from 'common/wtf-macro.html' import formField %}
<form action="" method="post">
    <table>
        {{ formField(form.username) }}
        {{ formField(form.userpass) }}
    </table>
        {{ form.submit() }}
</form>
</body>
</html>

巨集的程式碼

{% macro formField(field) %}
    <tr>
        <td>{{ field.label() }}</td>
        <td>{{ field() }}</td> {# form.username() 在這個位置實現 能新增 placeholder屬性 style class  #}
        <td>
            {% if field.errors %}
                <ul class="error">
                {% for error in field.errors %}
                    <li>{{ error }}</li>
                {% endfor %}
                </ul>
            {% endif %}
        </td>
    </tr>
{% endmacro %}
​
{#{{ formField(form.username)) }}#}

使用bootstrap渲染表單

{% extends 'common/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block page_content %}
    <div class="row">
        <div class="col-md-8"><img src="{{ url_for('static',filename='img/meinv.jpg') }}" alt=""></div>
        <div class="col-md-4">{{ wtf.quick_form(form) }}</div>
    </div>
{% endblock %}

注意:

  1. request.form 獲取不到表單get傳遞過來的資料

  2. 使用request.args 獲取get傳遞過來的資料

  3. 表單都使用post提交