中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

Python的Flask框架中web表單的教程
來源:易賢網 閱讀:972 次 日期:2015-04-24 10:49:51
溫馨提示:易賢網小編為您整理了“Python的Flask框架中web表單的教程”,方便廣大網友查閱!

下面為你介紹了Python的Flask框架中web表單的教程,表單是學習各個web框架中的基礎知識,需要的朋友可以參考下

概要

在前面章節我們為主頁定義了一個簡單的模板,部分尚未實現的模塊如用戶或帖子等使用模擬的對象作為臨時占位。

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

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

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

配置

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

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

CSRF_ENABLED = True

SECRET_KEY = 'you-will-never-guess'

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

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

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

from flask import Flask

app = Flask(__name__)

app.config.from_object('config')

from app import views

用戶登錄表單

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

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

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

開始我們的第一個表單吧 (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 這兩個字段。

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

表單模板

現在我們的問題就是需要一個顯示這個登錄表單的模板。好消息是我們剛剛創建的登錄表單類知道如何把字段轉換成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 繼承模板內容。我們會在后面創建的模板中繼續使用這種方式,這樣可以使我們所有的頁面布局保持一致。

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

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

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

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

表單視圖

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

這個函數相當的簡單無趣,因為我們只需要把表單對象傳遞給模板就行了。下面就是我們這個視圖函數的全部內容 (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 明白我們這個視圖函數支持 GET 和 POST 請求。否則這個視圖函數只會響應 GET 請求。我們需要得到用戶填寫表單后提交的數據,這些數據是從 POST 請求中傳遞過來的。

你可以通過在瀏覽器中測試這個程序來了解上面所說的。 按照視圖函數關聯的路由,你應該在瀏覽器中輸入

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

從表單中接收數據

另外值得一提的是, Flask-WTF 對表單提交數據的處理使我們的接下來要做的事情變得簡單了。下面就是我們這個登錄視圖函數的新版本, 加入了表單數據驗證和處理 (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() 這個方法做了表單處理的所有工作。如果你在表單向用戶提供數據時(舉個栗子:用戶在它之前修改了一下提交的數據) 時調用此方法,它會返回 False。發生這樣的情況時,你懂的。不懂?就是提交的數據驗證不通過,你要繼續渲染模板。

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

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

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

flash 函數提供的消息不會自動出現在我們的網站頁面中,所以我們需要做點事情讓它在頁面中顯示出來。為了讓我們所有頁面都能有這項激動人心的功能,所以就把它添加到基礎模板中吧, 下面是更新后的基礎模板 (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 消息的功能希望你能明白。

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

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

改善一下字段驗證

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

但似乎還少點什么。如果我們在用戶提交數據失敗后給用戶點提示,讓他們知道什么原因引起的,豈不妙哉!太幸運了,用 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 字段的右邊添加了一個循環語句,它會把openid字段驗證失敗的消息都顯示出來。不論你的表單有多少字段,所有表單字段驗證失敗的錯誤消息都可以用 form.errors.字段名 這種方式來使用。這個表單中我們的是 form.errors.openid。為了讓錯誤消息引起用戶的注意,我們還給消息添加了顯示紅色的 css 樣式。

處理 OpenID 登錄

現實生活中,我們發現有很多人都不知道他們擁有一些公共賬號。一部分大牌的網站或服務商都會為他們的會員提供公共賬號的認證。舉個栗子,如果你有一個 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' }]

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

@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 中引入了公共賬號服務商的配置列表,然后把它作為一個參數通過 render_template 函數引入到模板。

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

<!-- 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 鏈接后顯示的截圖:

名單

更多信息請查看IT技術專欄

更多信息請查看網絡編程
易賢網手機網站地址:Python的Flask框架中web表單的教程
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
亚洲免费一在线| 国产精品私拍pans大尺度在线| 在线观看日韩国产| 欧美日韩精品一本二本三本| 欧美日韩综合一区| 国产一级精品aaaaa看| 中文亚洲欧美| 欧美一级午夜免费电影| 欧美刺激性大交免费视频| 国产精品丝袜xxxxxxx| 韩国av一区二区| 亚洲一区二区精品| 欧美视频日韩视频| 亚洲美女精品一区| 欧美精品亚洲| 91久久国产综合久久| 欧美一级久久| 国产精品午夜电影| 香蕉国产精品偷在线观看不卡| 欧美激情无毛| 韩日精品视频一区| 亚洲夜间福利| 噜噜噜躁狠狠躁狠狠精品视频| 国产伦精品一区二区三区视频黑人| 最新中文字幕一区二区三区| 久久婷婷av| 国产欧美日韩视频| 欧美亚洲一区二区三区| 国产美女在线精品免费观看| 亚洲精品中文字幕在线| 国产精品亚洲综合久久| 亚洲图片欧美一区| 国产老肥熟一区二区三区| 欧美在线观看一二区| 国产亚洲一区在线| 亚洲欧美成人一区二区三区| 欧美日韩在线影院| 国产精品99久久久久久久久久久久 | 国内精品久久久久影院色| 欧美亚洲综合网| 伊人夜夜躁av伊人久久| 欧美日韩成人一区二区| 欧美一站二站| 亚洲日本成人| 国产精品v日韩精品| 久久天天躁夜夜躁狠狠躁2022 | 久久久久久久999精品视频| 国产亚洲毛片在线| 久久精品久久综合| 亚洲日本激情| 韩国成人理伦片免费播放| 欧美精品九九99久久| 亚洲色图制服丝袜| 国产亚洲欧美激情| 老司机精品视频一区二区三区| 国内精品国产成人| 欧美视频中文字幕| 欧美国产丝袜视频| 久久久www成人免费无遮挡大片| 亚洲一区二区精品在线观看| 亚洲精品欧美| 亚洲欧洲一区二区在线观看| 欧美性开放视频| 免费成年人欧美视频| 久久久五月婷婷| 久久精品国产第一区二区三区最新章节 | 精品成人国产| 国产精品红桃| 国产精品人成在线观看免费| 女人香蕉久久**毛片精品| 久久三级视频| 欧美有码视频| 久久久一区二区| 久久超碰97人人做人人爱| 欧美专区在线播放| 亚洲自拍都市欧美小说| 这里只有精品电影| 亚洲一级高清| 久久国产精品网站| 亚洲国产小视频| 在线亚洲精品| 国产精品99久久久久久久久久久久| 99视频在线观看一区三区| 亚洲日韩视频| 一区二区三区视频观看| 亚洲男女毛片无遮挡| 欧美专区福利在线| 欧美不卡激情三级在线观看| 久久人人看视频| 久久中文在线| 美女黄毛**国产精品啪啪| 久久久人成影片一区二区三区| 久久久精品动漫| 欧美成人首页| 国内自拍亚洲| 亚洲高清精品中出| 亚洲精品男同| 亚洲免费在线| 免费日韩av片| 欧美日韩另类综合| 国产视频观看一区| 亚洲理伦在线| 欧美在线亚洲综合一区| 农村妇女精品| 国产精品一区一区| 亚洲乱码国产乱码精品精可以看| 亚洲一区二区欧美| 欧美国产乱视频| 激情国产一区二区| 午夜精品久久久久久久| 欧美成人黄色小视频| 国户精品久久久久久久久久久不卡| 亚洲午夜在线观看| 欧美另类99xxxxx| 亚洲国产一区在线观看| 久久久久成人精品| 国产精品日日做人人爱| 亚洲天堂第二页| 欧美日韩中文字幕| 亚洲国产高清一区| 噜噜噜躁狠狠躁狠狠精品视频| 国产精品美女久久久久av超清| av成人免费在线| 欧美日韩视频在线一区二区观看视频 | 欧美激情影音先锋| 黄色日韩网站| 久久综合久久88| 国产有码在线一区二区视频| 亚洲一区二区视频| 欧美日韩视频在线一区二区| 在线精品视频在线观看高清| 蜜臀av在线播放一区二区三区| 国产精品视频一区二区高潮| 一本色道88久久加勒比精品 | 欧美午夜视频在线| 性伦欧美刺激片在线观看| 国产精品永久免费观看| 亚洲影音先锋| 在线观看日韩www视频免费| 久久久水蜜桃av免费网站| 国产一区二区中文字幕免费看| 久久中文字幕一区| 亚洲国产专区校园欧美| 欧美精品日韩| 亚洲精选国产| 国产精品美女www爽爽爽| 亚洲欧美国产不卡| 亚洲欧洲日产国码二区| 在线观看视频免费一区二区三区| 欧美福利一区二区| 午夜精品视频在线观看一区二区 | 欧美在线观看网址综合| 国产性猛交xxxx免费看久久| 久久野战av| 国产精品99久久不卡二区| 国产精品高清在线| 你懂的视频一区二区| 欧美亚洲免费| 亚洲一区在线直播| 一区二区三区你懂的| 国产一区二区三区在线观看视频 | 亚洲激情女人| 国产欧美一区二区三区视频| 欧美激情在线有限公司| 久久日韩粉嫩一区二区三区| 一区二区高清视频| 国产曰批免费观看久久久| 国产乱肥老妇国产一区二| 久久综合成人精品亚洲另类欧美| 99av国产精品欲麻豆| 亚洲美洲欧洲综合国产一区| 国内精品视频在线播放| 国内自拍视频一区二区三区| 国产欧美精品日韩| 国内外成人免费激情在线视频网站 | 欧美一区二区三区在线视频 | 亚洲午夜性刺激影院| 亚洲国产精彩中文乱码av在线播放| 国产农村妇女精品一二区| 国产欧美一区二区精品婷婷| 国产日韩欧美视频在线| 国产日韩在线不卡| 狠狠色综合网站久久久久久久| 国产偷国产偷精品高清尤物| 国内伊人久久久久久网站视频| 亚洲午夜久久久| 一本色道久久精品| 亚洲天堂av图片| 久久久xxx| 欧美高清视频在线观看| 欧美日韩在线精品| 国产精品亚洲不卡a| 亚洲国产一区二区a毛片| 亚洲精品精选| 亚洲女ⅴideoshd黑人| 久久在线视频在线| 欧美三级视频| 一区二区三区在线观看国产| 在线日韩日本国产亚洲| 亚洲精品免费在线|