国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - Python的Flask框架中web表單的教程

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

2020-06-10 09:16goldensun Python

這篇文章主要介紹了Python的Flask框架中web表單的教程,表單是學(xué)習(xí)各個web框架中的基礎(chǔ)知識,需要的朋友可以參考下

 概要

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

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

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

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

配置

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

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

?
1
2
CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'

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


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

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

?
1
2
3
4
5
6
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ù)器就行了。另外我們還需要在表單中加一個“記住我” 的選項框,這個是送給那些不想每次來我們網(wǎng)站都要進行身份認證的人。選擇這個選項后,首次登錄時會用cookie在他們的瀏覽器上記住他們的登錄信息,下次再進入網(wǎng)站時就不需要進行登錄操作。

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

?
1
2
3
4
5
6
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)

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

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


表單模板

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 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 繼承模板內(nèi)容。我們會在后面創(chuàng)建的模板中繼續(xù)使用這種方式,這樣可以使我們所有的頁面布局保持一致。


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

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


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

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

表單視圖

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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ù)只會響應(yīng) GET 請求。我們需要得到用戶填寫表單后提交的數(shù)據(jù),這些數(shù)據(jù)是從 POST 請求中傳遞過來的。

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

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

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

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

?
1
2
3
4
5
6
7
8
9
@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ù)) 時調(diào)用此方法,它會返回 False。發(fā)生這樣的情況時,你懂的。不懂?就是提交的數(shù)據(jù)驗證不通過,你要繼續(xù)渲染模板。

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

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


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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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ù)會通知用戶的瀏覽器跳轉(zhuǎn)到指定的地址。在我們的視圖函數(shù)中,我們使用它跳轉(zhuǎn)到了首頁。注意跳轉(zhuǎn)結(jié)束后頁面上還會顯示 flash 函數(shù)傳遞的消息哦。

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

改善一下字段驗證

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

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

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


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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 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)站或服務(wù)商都會為他們的會員提供公共賬號的認證。舉個栗子,如果你有一個 google 賬號,其實你就有了一個公共賬號,類似的還有 Yahoo, AOL, Flickr 等。

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


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

?
1
2
3
4
5
6
7
8
9
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ù)中使用這個列表了:
 

?
1
2
3
4
5
6
7
8
9
10
@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 中引入了公共賬號服務(wù)商的配置列表,然后把它作為一個參數(shù)通過 render_template 函數(shù)引入到模板。


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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!-- 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。當(dāng)用戶點擊相關(guān)的公共賬號鏈接時,需要用戶名的公共賬號會提示用戶輸入用戶名, javascript 會把用戶名處理成可用的公共賬號,最后再插入到 openid 字段的文本框中。
 

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

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

 結(jié)束語

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

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


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

下載地址:microblog-0.3.zip

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40 Weibo Article 41 Weibo Article 42
主站蜘蛛池模板: 免费视频一区二区 | 精品一区在线 | 国产精品美女久久久久aⅴ国产馆 | 免费观看av大片 | 久久中文字幕一区 | 色九九 | 国产一区日韩欧美 | 亚洲精品综合 | 国产在线小视频 | 日韩av一区二区在线观看 | 国产在线观看一区 | av短片在线| 亚洲一级黄色 | 亚洲欧美制服诱惑 | 亚洲人成在线播放 | 黄色日本视频 | 精品国产91亚洲一区二区三区www | 午夜爽爽爽 | 亚洲一区在线日韩在线深爱 | 黄色在线免费 | 亚洲久草| 亚洲精品电影网在线观看 | 久久99国产精一区二区三区 | a黄视频 | 视频一区中文字幕 | 欧美日韩在线一区 | 中文字幕国产一区 | 欧美日韩在线一区二区 | 亚洲色视频| 久草在线 | 精品国产一区二区三区久久久蜜 | 一区二区三区日韩 | 91av导航| 欧美日韩中文在线 | 在线视频不卡一区 | 亚洲视频自拍 | 亚洲视频三区 | 激情五月婷婷丁香 | 午夜激情视频在线观看 | 国产高潮呻吟av | 在线观看一区视频 |