最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python的Flask框架中web表單的教程

 更新時間:2015年04月20日 14:51:53   投稿:goldensun  
這篇文章主要介紹了Python的Flask框架中web表單的教程,表單是學習各個web框架中的基礎知識,需要的朋友可以參考下

 概要

在前面章節(jié)我們?yōu)橹黜摱x了一個簡單的模板,部分尚未實現(xiàn)的模塊如用戶或帖子等使用模擬的對象作為臨時占位。

本章我們將看到如何利用web表單填補這些空白。

web表單是web應用中最基本的構建要素,我們將通過表單來實現(xiàn)用戶發(fā)帖和應用登錄功能。

完成本章內容你需要基于前面章節(jié)完成的微博應用代碼,請確認這些代碼已安裝并能正常運行。

配置

Flask-WTF是WTForms項目的Flask框架擴展,我們將用他來幫助我們處理web表單。

大部分Flask擴展都需要定義相關配置項,所以我們先來在應用根目錄下創(chuàng)建一個配置文件以備使用。我們先這樣創(chuàng)建 (fileconfig.py):
 

CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'

很簡單吧,這是Flask-WTF需要用到的2個配置項。CSRF_ENABLED配置啟用了跨站請求攻擊保護,大部分情況下你都需要開啟此功能,這能使你的應用更安全。


SECRET_KEY設置當CSRF啟用時有效,這將生成一個加密的token供表單驗證使用,你要確保這個KEY足夠復雜不會被簡單推測。

現(xiàn)在這個配置文件已經(jīng)基本可用了。項目創(chuàng)建完成我們可以創(chuàng)建如下文件并編輯(fileapp/__init__.py):
 

from flask import Flask
 
app = Flask(__name__)
app.config.from_object('config')
 
from app import views

用戶登錄表單

使用Flask-WTF創(chuàng)建的表單就像一個對象,需要從Form類繼承子類。然后在這個子類中定義一些類的屬性變量作為表單字段就可以了。

我們要創(chuàng)建一個登錄表單,用來進行用戶身份識別。但跟平常需要驗證用戶名和密碼的登錄方式不同,我們將使用 OpenId 來處理登錄過程。使用OpenId的好處就是我們不用管那些用戶名和密碼的認證過程,交給 OpenId 去搞定,它會返回給我們用戶驗證后的數(shù)據(jù)。這樣對于使用我們網(wǎng)站的用戶而言也更安全。


使用 OpenId 登錄只需要一個字符串,然后發(fā)送給 OpenId 服務器就行了。另外我們還需要在表單中加一個“記住我” 的選項框,這個是送給那些不想每次來我們網(wǎng)站都要進行身份認證的人。選擇這個選項后,首次登錄時會用cookie在他們的瀏覽器上記住他們的登錄信息,下次再進入網(wǎng)站時就不需要進行登錄操作。

開始我們的第一個表單吧 (fileapp/forms.py):
 

from flask.ext.wtf import Form, TextField, BooleanField
from flask.ext.wtf import Required
 
class LoginForm(Form):
  openid = TextField('openid', validators = [Required()])
  remember_me = BooleanField('remember_me', default = False)

欣賞一下這個類,多么的簡潔,多么的一目了然。如此簡單,但又十分的富有內涵。我們引入了一個 Form 類,然后繼承這個類,按需求還添加了 TextField 和 BooleanField 這兩個字段。

另外還引入了一個表單驗證函數(shù) Required,這種驗證函數(shù)可以附加在字段里面,在用戶提交表單時它們會用來檢查用戶填寫的數(shù)據(jù)。這個 Required 函數(shù)是用來防止用戶提交空數(shù)據(jù)。Flask-WTF 中還有很多不同作用的表單驗證函數(shù),我們將會在后面使用到它們。


表單模板

現(xiàn)在我們的問題就是需要一個顯示這個登錄表單的模板。好消息是我們剛剛創(chuàng)建的登錄表單類知道如何把字段轉換成HTML,所以我們只需要把注意力集中到頁面布局上。下面就是我們的登錄表單的模板 (fileapp/templates/login.html):
 

<!-- extend from base layout -->
{% extends "base.html" %}
 
{% block content %}
<h1>Sign In</h1>
<form action="" method="post" name="login">
  {{form.hidden_tag()}}
  <p>
    Please enter your OpenID:<br>
    {{form.openid(size=80)}}<br>
  </p>
  <p>{{form.remember_me}} Remember Me</p>
  <p><input type="submit" value="Sign In"></p>
</form>
{% endblock %}

容我啰嗦一下,在這個模板中,我們又一次使用了模板繼承的方式。使用 extends 語句從 base.html 繼承模板內容。我們會在后面創(chuàng)建的模板中繼續(xù)使用這種方式,這樣可以使我們所有的頁面布局保持一致。


這個登錄模板跟普通的HTML表單有些明顯的區(qū)別,它使用模板參數(shù) {{ ... }} 來實例化表單字段,而表單字段又來源于我們剛剛定義的表單類,模板參數(shù)中使用了 form 這個名稱。當我們使用視圖函數(shù)引用表單類并渲染到模板時,我們要特別注意這個把表單類傳遞到模板的變量名。

我們在配置中開啟了CSRF(跨站偽造請求)功能,模板參數(shù) {{ form.hidden_tag() }} 會被替換成一個具有防止CSRF功能的隱藏表單字段。在開啟了CSRF功能后,所有模板的表單中都需要添加這個模板參數(shù)。


我們定義的表單對象中的字段同樣也能被模板渲染,只需要在模板合適的位置添加類似于 {{ form.field_name }} 這樣的模板參數(shù),相關字段就會在被定義的位置出現(xiàn)。另外還有一些字段是可以傳參數(shù),比如這個 openid 字段,我們就添加了一個參數(shù)讓它顯示的寬度增加到80個字符。

由于我們沒有在表單中定義一個提交功能的按鈕,所以在這里只能以普通表單字段的方式來做了。不過說起來區(qū)區(qū)一個按鈕,在表單中跟任何數(shù)據(jù)都沒有關系,的確也沒有在表單類中定義的必要。

表單視圖

見證奇跡的時刻最后一步,我們馬上要來寫一個渲染登錄表單對象到模板的視圖函數(shù)。

這個函數(shù)相當?shù)暮唵螣o趣,因為我們只需要把表單對象傳遞給模板就行了。下面就是我們這個視圖函數(shù)的全部內容 (fileapp/views.py):
 

from flask import render_template, flash, redirect
from app import app
from forms import LoginForm
 
# index view function suppressed for brevity
 
@app.route('/login', methods = ['GET', 'POST'])
def login():
  form = LoginForm()
  return render_template('login.html',
    title = 'Sign In',
    form = form)

我們引入登錄表單類,然后把它實例化到一個變量,最后再把這個變量傳給模板。要渲染表單字段必須的事情也就這些。

上面的代碼中還引入了兩個新對象: falsh 和 redirect, 這個先甭理它們,稍后才用得上。


另外還做了一件事就是在路由裝飾器中添加一個新方法。讓 Flask 明白我們這個視圖函數(shù)支持 GET 和 POST 請求。否則這個視圖函數(shù)只會響應 GET 請求。我們需要得到用戶填寫表單后提交的數(shù)據(jù),這些數(shù)據(jù)是從 POST 請求中傳遞過來的。

你可以通過在瀏覽器中測試這個程序來了解上面所說的。 按照視圖函數(shù)關聯(lián)的路由,你應該在瀏覽器中輸入 http://localhost:5000/login

由于我們還沒有寫任何接收數(shù)據(jù)的代碼,所以現(xiàn)在你在頁面中點提交按鈕還沒有任何效果。

從表單中接收數(shù)據(jù)

另外值得一提的是, Flask-WTF 對表單提交數(shù)據(jù)的處理使我們的接下來要做的事情變得簡單了。下面就是我們這個登錄視圖函數(shù)的新版本, 加入了表單數(shù)據(jù)驗證和處理 (fileapp/views.py):
 

@app.route('/login', methods = ['GET', 'POST'])
def login():
  form = LoginForm()
  if form.validate_on_submit():
    flash('Login requested for OpenID="' + form.openid.data + '", remember_me=' + str(form.remember_me.data))
    return redirect('/index')
  return render_template('login.html',
    title = 'Sign In',
    form = form)

validate_on_submit() 這個方法做了表單處理的所有工作。如果你在表單向用戶提供數(shù)據(jù)時(舉個栗子:用戶在它之前修改了一下提交的數(shù)據(jù)) 時調用此方法,它會返回 False。發(fā)生這樣的情況時,你懂的。不懂?就是提交的數(shù)據(jù)驗證不通過,你要繼續(xù)渲染模板。

在提交請求時調用了表單的 validate_on_submit() 方法后,它會從請求中獲取所有提交的數(shù)據(jù),然后使用表單字段中綁定的驗證函數(shù)進行數(shù)據(jù)驗證。在所有的數(shù)據(jù)都驗證通過時會返回 True. 這就意味著你可以放心的使用這些表單數(shù)據(jù)了。

只要有一個字段驗證不通過,它都會返回 False. 這時就需要我們返回數(shù)據(jù)給用戶,讓他們來糾正一下錯誤數(shù)據(jù)。接下來我們將會看到在數(shù)據(jù)驗證失敗時,如何把錯誤消息顯示給用戶。


當 validate_on_submit() 方法返回 True 的時候,我們的視圖函數(shù)又會調用兩個新的函數(shù)。它們都是從Flask 中引入的,flash 函數(shù)用來在下一個打開的頁面中顯示定義的消息。我們現(xiàn)在用它用來做調試。因為我們現(xiàn)在還沒有做用戶登錄模塊, 所以只需要把用戶提交上來的數(shù)據(jù)顯示一下就行了。flash 函數(shù)非常有用,比如為用戶的一些操作提供消息反饋。

flash 函數(shù)提供的消息不會自動出現(xiàn)在我們的網(wǎng)站頁面中,所以我們需要做點事情讓它在頁面中顯示出來。為了讓我們所有頁面都能有這項激動人心的功能,所以就把它添加到基礎模板中吧, 下面是更新后的基礎模板 (fileapp/templates/base.html):
 

<html>
 <head>
  {% if title %}
  <title>{{title}} - microblog</title>
  {% else %}
  <title>microblog</title>
  {% endif %}
 </head>
 <body>
  <div>Microblog: <a href="/index">Home</a></div>
  <hr>
  {% with messages = get_flashed_messages() %}
  {% if messages %}
  <ul>
  {% for message in messages %}
    <li>{{ message }} </li>
  {% endfor %}
  </ul>
  {% endif %}
  {% endwith %}
  {% block content %}{% endblock %}
 </body>
</html>

模板中顯示 flash 消息的功能希望你能明白。


在視圖函數(shù)中我們使用的另一個新函數(shù)就是 redirect. 這個函數(shù)會通知用戶的瀏覽器跳轉到指定的地址。在我們的視圖函數(shù)中,我們使用它跳轉到了首頁。注意跳轉結束后頁面上還會顯示 flash 函數(shù)傳遞的消息哦。

激動人心的時刻到了,運行我們的程序吧,看看表單是如何工作的吧。不要填寫表單中的 openid 字段,看看 Required 這個驗證函數(shù)是如何發(fā)揮威力,把一切發(fā)起空數(shù)據(jù)的請求阻止在千里之外。

改善一下字段驗證

我們程序目前狀況不錯,提交不合要求的數(shù)據(jù)會被阻止,還會返回表單讓用戶修改,基本滿足我們要求。

但似乎還少點什么。如果我們在用戶提交數(shù)據(jù)失敗后給用戶點提示,讓他們知道什么原因引起的,豈不妙哉!太幸運了,用 Flask-WTF 可以輕松解決這個問題。

當表單字段驗證失敗時, Flask-WTF 會添加一個錯誤消息到表單對象。這些消息在模板中也是可以使用的,所以我們只需要在模板中添加一點點東西就OK了。


這個就是我們添加了驗證消息的登錄模板 (fileapp/templates/login.html):
 

<!-- extend base layout -->
{% extends "base.html" %}
 
{% block content %}
<h1>Sign In</h1>
<form action="" method="post" name="login">
  {{form.hidden_tag()}}
  <p>
    Please enter your OpenID:<br>
    {{form.openid(size=80)}}<br>
    {% for error in form.errors.openid %}
    <span style="color: red;">[{{error}}]</span>
    {% endfor %}<br>
  </p>
  <p>{{form.remember_me}} Remember Me</p>
  <p><input type="submit" value="Sign In"></p>
</form>
{% endblock %}

我們僅在 openid 字段的右邊添加了一個循環(huán)語句,它會把openid字段驗證失敗的消息都顯示出來。不論你的表單有多少字段,所有表單字段驗證失敗的錯誤消息都可以用 form.errors.字段名 這種方式來使用。這個表單中我們的是 form.errors.openid。為了讓錯誤消息引起用戶的注意,我們還給消息添加了顯示紅色的 css 樣式。
 
處理 OpenID 登錄

現(xiàn)實生活中,我們發(fā)現(xiàn)有很多人都不知道他們擁有一些公共賬號。一部分大牌的網(wǎng)站或服務商都會為他們的會員提供公共賬號的認證。舉個栗子,如果你有一個 google 賬號,其實你就有了一個公共賬號,類似的還有 Yahoo, AOL, Flickr 等。

為了方便我們的用戶能簡單的使用他們的公共賬號,我們將把這些公共賬號的鏈接添加到一個列表,這樣用戶就不用自手工輸入了。


我們要把一些提供給用戶的公共賬號服務商定義到一個列表里面,這個列表就放到配置文件中吧 (fileconfig.py):
 

CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'
 
OPENID_PROVIDERS = [
  { 'name': 'Google', 'url': 'https://www.google.com/accounts/o8/id' },
  { 'name': 'Yahoo', 'url': 'https://me.yahoo.com' },
  { 'name': 'AOL', 'url': 'http://openid.aol.com/<username>' },
  { 'name': 'Flickr', 'url': 'http://www.flickr.com/<username>' },
  { 'name': 'MyOpenID', 'url': 'https://www.myopenid.com' }]

接下來就是要在我們的登錄視圖函數(shù)中使用這個列表了:
 

@app.route('/login', methods = ['GET', 'POST'])
def login():
  form = LoginForm()
  if form.validate_on_submit():
    flash('Login requested for OpenID="' + form.openid.data + '", remember_me=' + str(form.remember_me.data))
    return redirect('/index')
  return render_template('login.html',
    title = 'Sign In',
    form = form,
    providers = app.config['OPENID_PROVIDERS'])

我們從 app.config 中引入了公共賬號服務商的配置列表,然后把它作為一個參數(shù)通過 render_template 函數(shù)引入到模板。


接下來要做的我想你也猜得到,我們需要在登錄模板中把這些服務商鏈接顯示出來。
 

<!-- extend base layout -->
{% extends "base.html" %}
 
{% block content %}
<script type="text/javascript">
function set_openid(openid, pr)
{
  u = openid.search('<username>')
  if (u != -1) {
    // openid requires username
    user = prompt('Enter your ' + pr + ' username:')
    openid = openid.substr(0, u) + user
  }
  form = document.forms['login'];
  form.elements['openid'].value = openid
}
</script>
<h1>Sign In</h1>
<form action="" method="post" name="login">
  {{form.hidden_tag()}}
  <p>
    Please enter your OpenID, or select one of the providers below:<br>
    {{form.openid(size=80)}}
    {% for error in form.errors.openid %}
    <span style="color: red;">[{{error}}]</span>
    {% endfor %}<br>
    |{% for pr in providers %}
    <a href="javascript:set_openid('{{pr.url}}', '{{pr.name}}');">{{pr.name}}</a> |
    {% endfor %}
  </p>
  <p>{{form.remember_me}} Remember Me</p>
  <p><input type="submit" value="Sign In"></p>
</form>
{% endblock %}

這次的模板添加的東西似乎有點多。一些公共賬號需要提供用戶名,為了解決這個我們用了點 javascript。當用戶點擊相關的公共賬號鏈接時,需要用戶名的公共賬號會提示用戶輸入用戶名, javascript 會把用戶名處理成可用的公共賬號,最后再插入到 openid 字段的文本框中。
 

下面這個是在登錄頁面點擊 google 鏈接后顯示的截圖: 

2015420144353250.jpg (450×300)

 結束語

我們目前在用戶登錄表單中取得了一些進展,但用戶登入這個網(wǎng)站還是啥事兒都不能干。目前我們還一直在登錄的界面上小打小鬧,是因為我們還沒有記錄一切的數(shù)據(jù)庫。

所以從下節(jié)開始,我們將會整一個數(shù)據(jù)庫起來,然后真正完成我們的登錄系統(tǒng)。不要走開,請繼續(xù)關注。


微博(microblog) 當前版本源碼從下面地址下載:

下載地址:microblog-0.3.zip

相關文章

  • Python編程深度學習計算庫之numpy

    Python編程深度學習計算庫之numpy

    今天小編就為大家分享一篇關于Python編程深度學習計算庫之numpy,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Python下opencv圖像閾值處理的使用筆記

    Python下opencv圖像閾值處理的使用筆記

    這篇文章主要介紹了Python下opencv圖像閾值處理的使用筆記,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • python猜數(shù)字小游戲實現(xiàn)代碼

    python猜數(shù)字小游戲實現(xiàn)代碼

    大家好,本篇文章主要講的是python猜數(shù)字小游戲實現(xiàn)代碼,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 詳解Python3序列賦值、序列解包

    詳解Python3序列賦值、序列解包

    這篇文章主要介紹了Python3序列賦值、序列解包的相關知識,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-05-05
  • 對python生成業(yè)務報表的實例詳解

    對python生成業(yè)務報表的實例詳解

    今天小編就為大家分享一篇對python生成業(yè)務報表的實例詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • python3 實現(xiàn)mysql數(shù)據(jù)庫連接池的示例代碼

    python3 實現(xiàn)mysql數(shù)據(jù)庫連接池的示例代碼

    這篇文章主要介紹了python3 實現(xiàn)mysql數(shù)據(jù)庫連接池的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • python用tkinter實現(xiàn)一個簡易能進行隨機點名的界面

    python用tkinter實現(xiàn)一個簡易能進行隨機點名的界面

    這篇文章主要介紹了python用tkinter實現(xiàn)一個簡易能進行隨機點名的界面,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • 十個Python自動化常用操作,即拿即用

    十個Python自動化常用操作,即拿即用

    這篇文章主要介紹了十個Python自動化常用操作,即拿即用,文中有非常詳細的代碼示例,對正在學習python的小伙伴們有很好的幫助喲,需要的朋友可以參考下
    2021-05-05
  • Python爬蟲庫requests-html進行HTTP請求HTML解析等高級功能應用

    Python爬蟲庫requests-html進行HTTP請求HTML解析等高級功能應用

    這篇文章主要為大家介紹了Python爬蟲庫requests-html進行HTTP請求HTML解析JavaScript渲染以及更高級的功能應用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Python Pytorch深度學習之神經(jīng)網(wǎng)絡

    Python Pytorch深度學習之神經(jīng)網(wǎng)絡

    今天小編就為大家分享一篇關于Pytorch神經(jīng)網(wǎng)絡的文章,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-10-10

最新評論

新巴尔虎右旗| 广州市| 黔西县| 花垣县| 台东市| 龙山县| 璧山县| 马关县| 彭阳县| 曲阳县| 毕节市| 连城县| 永清县| 惠水县| 忻城县| 大庆市| 天水市| 滨海县| 白沙| 扶风县| 台江县| 罗田县| 咸宁市| 朝阳市| 慈利县| 双辽市| 兴山县| SHOW| 东兰县| 呼图壁县| 镇雄县| 芜湖县| 华宁县| 五原县| 河津市| 宁明县| 兴仁县| 贵定县| 金阳县| 富民县| 盐边县|