天天看點

Flask—03-bootstrap與表單

bootstrap與表單

Bootstrap是美國Twitter公司的設計師Mark Otto和Jacob Thornton合作基于HTML、CSS、JavaScript 開發的簡潔、直覺、強悍的前端開發架構,使得 Web 開發更加快捷. Bootstrap提供了優雅的HTML和CSS規範,它即是由動态CSS語言Less寫成。Bootstrap一經推出後頗受歡迎,一直是GitHub上的熱門開源項目,包括NASA的MSNBC(微軟全國廣播公司)的BreakingNews都使用了該項目。國内一些移動開發者較為熟悉的架構,如WeX5前端開源架構等,也是基于Bootstrap源碼進行性能優化而來。

flask-boostrap

  • 說明:在flask中使用bootstrap,可以通過該擴充庫完成。
  • 安裝:

    pip install flask-bootstrap

  • 使用:
    from flask_bootstrap import Bootstrap
    
    bootstrap = Bootstrap(app)
               
  • 模闆
    {# 繼承自bootstrap基礎模闆 #}
    {% extends \'bootstrap/base.html\' %}
    
    {% block title %}标題{% endblock %}
    
    {% block content %}
        <div class="container">預設内容</div>
    {% endblock %}
               
  • bootstrap基礎模闆中的block
    block 說明
    doc 整個HTML文檔
    html 整個html标簽
    head 整個head标簽
    metas 一組meta标簽
    styles 一組link标簽
    body 整個body标簽
    navbar 導覽列
    content 頁面内容
    scripts 一組scripts标簽
    提示:當重寫一個block後,原來的顯示效果全沒了,很可能是因為沒有寫

    {{ super() }}

加載靜态資源

  • flask中靜态資源預設存放在static目錄下,是以目錄結構如下:
    project/        # 項目目錄
        manage.py            # 啟動控制檔案
        templates/            # 模闆檔案目錄
        static/                # 靜态資源目錄
            img/                # 圖檔
            css/                # css檔案
            js/                    # js檔案
            favicon.ico            # 收藏夾圖示
               
  • 加載靜态資源檔案
    {# 繼承自自定義的基礎模闆 #}
    {% extends \'base.html\' %}
    
    {% block title %}使用者登入{% endblock %}
    
    {% block page_content %}
        <h1>歡迎登入...</h1>
        <div class="test"></div>
        {# 加載圖檔資源 #}
        {# 靜态資源加載的目錄static,提前在img檔案夾儲存一個圖檔xxx.jpg #}
        <img width="300" src="{{ url_for(\'static\', filename=\'img/xxx.jpg\') }}">
    {% endblock %}
    
    {% block styles %}
        {{ super() }}
        {# 加載CSS檔案:css檔案可以從bootstrap中粘貼一個過來 #}
        <link href="{{ url_for(\'static\', filename=\'css/common.css\') }}" type="text/css" rel="stylesheet" />
    {% endblock %}
    
    {% block head %}
        {{ super() }}
        {# 加載網站收藏夾小圖示:ico檔案自行從百度下載下傳一個ico檔案 #}
        <link rel="icon" type="image/x-icon" href="{{ url_for(\'static\', filename=\'favicon.ico\') }}" />
    {% endblock %}
    
    {% block scripts %}
        {{ super() }}
        {# 加載JS檔案:js檔案可以從bootstrap中粘貼一個過來 #}
        <script type="text/javascript" src="{{ url_for(\'static\', filename=\'js/common.js\') }}"></script>
    {% endblock %}
               

原生表單

  • 準備模闆檔案
    <form method="get" action="{{ url_for(\'check\') }}">
        使用者名:<input name="username" /><br />
        <input type="submit" />
    </form>
               
  • 添加視圖函數,渲染模闆檔案
    @app.route(\'/login/\')
    def login():
        return render_template(\'login.html\')
               
  • 校驗送出的請求
    @app.route(\'/check/\', methods=[\'GET\', \'POST\'])
    def check():
        # args:所有的GET參數
        # return request.args.get(\'username\', \'送出失敗\')
        # form:所有的POST參數
        # return request.form.get(\'username\', \'送出失敗\')
        # values:所有的GET/POST參數
        return request.values.get(\'username\', \'送出失敗\')
               
  • 一個路由可以接收多種請求
    @app.route(\'/login/\', methods=[\'GET\', \'POST\'])
    def login():
        if request.method == \'POST\':
            return request.form.get(\'username\', \'登入失敗\')
        return render_template(\'login.html\')
               

flask-wtf

  • 說明:表單處理的擴充庫,提供了CSRF、字段校驗等實用功能,實用非常友善。
  • 安裝:

    pip install flask-wtf

  • 使用:
    • 建立表單類:
    # 導入表單類的基類
    from flask_wtf import FlaskForm
    # 導入字段類型
    from wtforms import StringField, SubmitField
    # 導入相關驗證器
    from wtforms.validators import Length
    
    # 建立表單類
    class NameForm(FlaskForm):
        # name = StringField(\'使用者名\')
        # submit = SubmitField(\'送出\')
        name = StringField(\'使用者名\', validators=[Length(3, 6, message=\'使用者名必須是3~6個字元\')])
        submit = SubmitField(\'送出\')
               
    • 添加視圖函數,建立表單對象,并配置設定的模闆中
    @app.route(\'/\', methods=[\'GET\', \'POST\'])
      def index():
          # 建立表單對象
          form = NameForm()
          # 判斷是否是有效的送出
          if form.validate_on_submit():
              return form.name.data
          # 在模闆檔案中渲染表單,form.html可以自己寫一個,也可以百度一個
          return render_template(\'form.html\', form=form)
               
  • 原生渲染表單
    {# 原生渲染 #}
    <form method="post">
        {# CSRF字段 #}
        {{ form.hidden_tag() }}
        {# name字段 #}
        {{ form.name.label() }}{{ form.name(id=\'xx\', class=\'yy\') }}
        {% for e in form.name.errors %}
            <div>{{ e }}</div>
        {% endfor %}
        {# 送出按鈕 #}
        {{ form.submit() }}
    </form>
               
  • 使用bootstrap進行渲染
    {% extends \'bootstrap/base.html\' %}
    
    {# 導入快速渲染表單的宏 #}
    {% from \'bootstrap/wtf.html\' import quick_form %}
    
    {% block title %}bootstrap渲染表單類{% endblock %}
    
    {% block content %}
        <div class="container">
            {# 在合适的位置渲染表單 #}
            {{ quick_form(form) }}
        </div>
    {% endblock %}
               
  • POST重定向到GET:浏覽器會記錄最後的請求狀态,若最後請求時POST,點選重新整理時會提示再次送出表單。
    @app.route(\'/\', methods=[\'GET\', \'POST\'])
    def index():
        # 建立表單對象
        form = NameForm()
        # 判斷是否是有效的送出
        if form.validate_on_submit():
            session[\'name\'] = form.name.data
            return redirect(url_for(\'index\'))
        name = session.get(\'name\')
        # 在模闆檔案中渲染表單
        return render_template(\'form2.html\', form=form, name=name)
               
  • 常見字段類型:請自行測試
    字段類型 說明
    StringField 普通文本
    SubmitField 送出按鈕
    PasswordField 密文文本
    HiddenField 隐藏字段
    RadioField 單選框
    BooleanField 複選框
    SelectField 下拉框
    FileField 檔案上傳
    TextAreaField 文本域
    IntegerField 文本字段,值為整數
    FloatField 文本字段,值為浮點數
    DateField datetime.date類型
    DateTimeField datetime.datetime類型
  • 常見驗證器:請自行測試
    驗證器 說明
    Length 規定字元長度
    DataRequired 確定字段有值(提示資訊與所寫的不一緻)
    Email 郵箱格式
    IPAddress IP位址
    NumberRange 數值的範圍
    URL 統一資源定位符格式
    EqualTo 驗證兩個字段的一緻性
    Regexp 正則校驗
  • 自定義字段驗證函數
    # 建立表單類
    class NameForm(FlaskForm):
          。。。
        # 字段校驗函數:\'validate_字段名\'
        def validate_name(self, field):
            if len(field.data) < 6:
                raise ValidationError(\'使用者名不能少于6個字元\')
               

消息閃爍

  • 說明:

    當使用者送出請求後,狀态發生了改變,需要系統給出警告提示等資訊時,通常都是彈出一條消息,訓示使用者下一步的操作,使用者可以手動關閉或自動消失,整個過程不會影響頁面的正常顯示。

  • 使用:
    • 在需要閃爍消息時,使用

      flash

      函數儲存閃爍消息
    @app.route(\'/\', methods=[\'GET\', \'POST\'])
    def index():
        # 建立表單對象
        form = NameForm()
        # 判斷是否是有效的送出
        if form.validate_on_submit():
            # 最後一次送出的名字
            last_name = session.get(\'name\')
            # 如果存在最後送出的名字,且最後送出的名字與之前儲存的名字不相同時
            if last_name and last_name != form.name.data:
                flash(\'大哥,又換名字了^_^\')
            session[\'name\'] = form.name.data
            return redirect(url_for(\'index\'))
        name = session.get(\'name\')
        # 在模闆檔案中渲染表單
        return render_template(\'form2.html\', form=form, name=name)
               
    • 在模闆檔案中提供

      get_flashed_messages

      函數擷取閃爍消息并渲染:
    {% for message in get_flashed_messages() %}
    {# 閃爍消息檔案可以從bootstrap中粘貼一個過來 #}
    <div class="alert alert-warning alert-dismissible" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span>
        </button>
        {{ message }}
    </div>
    {% endfor %}
               
    說明:上面是從bootstrap粘貼的可消失的警告框。

flask-moment

  • 說明:專門負責資料本地化顯示的擴充庫,使用非常友善。
  • 安裝:

    pip install flask-moment

  • 使用:
    • python代碼:
    from flask_moment import Moment
    
    moment = Moment(app)
    
    @app.route(\'/moment/\')
    def mom():
        from datetime import datetime, timedelta
        current_time = datetime.utcnow() + timedelta(seconds=-360)
        return render_template(\'mom.html\', current_time=current_time)
               
    • 模闆檔案:
    {# 加載jQuery:依賴 #}
    {{ moment.include_jquery() }}
    
    {# 加載moment #}
    {{ moment.include_moment() }}
    
    {# 設定語言 #}
    {{ moment.locale(\'zh-CN\') }}
    
    {# 簡單的格式化時間顯示 #}
    <div>時間:{{ moment(current_time).format(\'LLLL\') }}</div>
    <div>時間:{{ moment(current_time).format(\'LLL\') }}</div>
    <div>時間:{{ moment(current_time).format(\'LL\') }}</div>
    <div>時間:{{ moment(current_time).format(\'L\') }}</div>
    
    {# 自定義格式化時間顯示:如2018-05-20 01:03:14 #}
    <div>自定義:{{ moment(current_time).format(\'YYYY-MM-DD HH:mm:ss\') }}</div>
    
    {# 顯示時間差 #}
    <div>發表于:{{ moment(current_time).fromNow() }}</div>