flask框架安装
flask框架安裝
pip install flask --user1.0程序的基本架構
1.1初始化
所有Flask程序都必須新建一個程序實例。WEB服務器把接收的客戶端所有請求轉交給這個對象處理。
# 如何初始化Flask對象實例 from flask import Flask app = Flask(__name__) # __name__參數決定程序根目錄,以便能夠找到向對于于根目錄的資源文件位置。1.2路由和視圖函數
Flask實例需要知道URL和函數之間的關系,Flask保存了一個函數映射表稱之為路由。
@app.route('/') def index():return "Hello_World"在這個過程中,index()就是視圖函數,視圖函數里可以返回html或者復雜的表單。
@app.route('/<name>') def user(name): # 這里參數千萬不能丟了return "Hello,%s" % (name)1.3開啟服務器
Flask實例run方法來啟動服務器。
if __name__=="__main__":# 添加__name__=="__main__",當前腳本被導入的時候不會當作一個新的服務器開啟。app.run()2.0請求-響應循環
請求對象request
from flask import request2.1 程序和請求上下文
| request | 程序上下文 | 處理請求時用作臨時存儲的對象。每次請求都會重設這個變量 |
| session | 程序上下文 | 請求對象,封裝了客戶端發出的 HTTP 請求中的內容 |
| current_app | 程序上下文 | 用戶會話,用于存儲請求之間需要“記住”的值的詞典 |
2.2請求調度
程序生成客戶端發來的請求,要找到該請求的視圖函數。為了完成這個任務,Flask會在程序的URL映射中查找請求的URL隨后找到相對應的視圖函數。
映射關系可以通過@app.route或者app.add_url_rule()來添加
映射關系可以通過app.url_map來查看
2.3 請求鉤子
通過裝飾器為一個模塊添加請求鉤子, 對當前模塊的請求進行額外的處理. 比如權限驗證.
2.4響應
2.4.1自定義返回狀態碼
一般的情況下我們的程序會對http請求返回一個200狀態碼代表這個請求已經處理成功,這里演示一下如何自定義返回狀態碼。
@app.route('/') def index():return "Hello",4002.4.2設置Cookie
from flask import make_response @app.route('/') def index():response = make_response("<h1>WEB</h1>")response.set_cookie('Haozhan',"19")return response2.4.3重定向
from flask import redirect @app.route('/') def index():return redirect("http://www.baidu.com")2.4.4abort
一種特殊的響應由 abort 函數生成,用于處理錯誤。
@app.route('/') def index():abort(404)3.0模板
3.1JinJa2模板引擎
首先,你需要在腳本目錄下新建一個文件夾,名字為:templates。
下面是在templates文件夾里新建的index.html內容
下面是在腳本目錄下新建的main.py文件內容
from flask import Flask from flask import render_template app = Flask(__name__)@app.route('/') def index():return render_template("index.html")if __name__=="__main__":app.run(debug=True)3.1.1渲染模板
<h1>Hello,{{ name }}</h1>上面是傳入參數的index.html
下面是main.py文件的內容
3.1.2變量
3.1.1例子中使用的{{ name }}實際上是一個占位符,告訴模板需要獲取數據的時候從服務器獲取。占位符可以識別所有類型的變量。
<p>A value from a dictionary: {{ mydict['key'] }}.</p> <p>A value from a list: {{ mylist[3] }}.</p> <p>A value from a list, with a variable index: {{ mylist[myintvar] }}.</p> <p>A value from an object's method: {{ myobj.somemethod() }}.</p>3.1.2.1過濾器
{{ name| safe }}| safe | 渲染值時不轉義 |
| capitalize | 把值的首字母轉換成大寫,其他字母轉換成小寫|
| lower | 把值轉換成小寫形式|
| upper | 把值轉換成大寫形式|
| title | 把值中每個單詞的首字母都轉換成大寫|
| trim | 把值的首尾空格去掉|
| striptags | 渲染之前把值中所有的 HTML 標簽都刪掉|
_提示,在不信任的用戶輸入地方。千萬不要使用safe進行渲染。不然會解析元素造成安全隱患。
3.1.3控制結構
3.1.3.1模板IF
{% if name %}{{ name }} {% else %}Hello World. {% endif %} # TYPE A @app.route('/') def index():name = Nonereturn render_template("index.html") # TYPE B @app.route('/') def index():name = [1,2,3,5]return render_template("index.html",name=name)我們來比較一下TYPEA和TYPEB有何不同,A未傳入name的值,而B在name的位置傳入的一個數組。將值傳入{% if name %}后,A會執{% else %}里的數據,而B則會執行{% else %}之前的數據。這便是不同之處。
3.1.3.2模板for
@app.route('/') def index():name = [1,2,3,5]return render_template("index.html",name=name) {% for i in name %}<li>{{ i }}</li> {% endfor %}- 下面的例子作為擴展,可以向主頁傳遞消息 -
3.1.3.3宏
宏的作用就類似于Python中的函數,使用關鍵字macro進行定義,可傳入參數。
{% macro input(name,age=18) %} # 參數age的默認值為18<input type='text' name="{{ name }}" value="{{ age }}" >{% endmacro %}調用
{{ input("haozhan",19) }}除了直接調用,你還可以把宏存入文件中在使用時調用,例如這樣。
{% include "news.html" %}另一種強大的功能則是類似于Python中的類繼承
<html> <head> { % block head % } <title>{ % block title % }{ % endblock % } - My Application</title> { % endblock % } </head> <body> { % block body % } { % endblock % } </body> </html>我們首先創建一個實例,再以繼承這個實例的基礎上創建另一個實例。
{% extends "new.html" %} {% block title %}Index{% endblock %} {% block head %} {{ super() }} <style> </style> {% endblock %} {% block body %} <h1>Hello, World!</h1> {% endblock %}因為原來的{% block head %}里面不是空的,所以在子模板中要使用{{ super() }}獲取原來的內容。
3.2使用 Flask-Bootstrap 集成 Twitter Bootstrap
Bootstrap 是客戶端框架,因此不會直接涉及服務器。服務器需要做的只是提供引用了
Bootstrap 層 疊 樣 式 表(CSS) 和 JavaScript 文 件 的 HTML 響 應, 并 在 HTML、CSS 和
JavaScript 代碼中實例化所需組件。這些操作最理想的執行場所就是模板。
導入bootstrap并完成初始化
from flask_bootstrap import Bootstrap app = Flask(__name__) bootstrap = Bootstrap(app)模板導入bootstrap/base.html
{% extends "bootstrap/base.html" %} {% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <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="/">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> <div class="page-header"> <h1>Hello, {{ name }}!</h1> </div> </div> {% endblock %}3.3自定義錯誤頁面
像常規路由一樣,Flask 允許程序使用基于模板的自定義錯誤頁面。
@app.errorhandler(404) def error404(e):return "這里啥都沒有哦",404和視圖函數一樣,錯誤處理函數也會返回響應和與之匹配的狀態碼。錯誤處理函數需要使用@errorhandler來注冊,需要在函數中傳入一個值.
3.4鏈接
url_for() # 該函數主要用于輔助知道url3.5靜態文件
當我們需要使用到靜態文件的時候,我們在程序根目錄下建立一個目錄static。在那之后我們需要將使用到的靜態資源放入static中,在程序中可以直接引用。
<img src="/static/1.jpg" />4.0表單
4.1跨展請求偽造保護
默認情況下,Flask-wtf能保護所有表單免首CSRF攻擊。
app.config['SECRET_KEY'] = 'hard guess string'-
- 通常為了增強安全性,密鑰不應該被直接寫入代碼中,而應該被寫入環境變量中。
4.2表單類
在使用Flask-wtf時,每個WEB表單都由一個繼承自Form的類表示
from flask_wtf import From from wtforms import StringField from wtforms.validators import Requiredclass NameFrom(From):name = StringField("What is your name?",validators=[Required()])submit = SubmitField('Submit')WTForms支持的HTML標準字段
- StringField 文本字段
- TextAreaField 多行文本字段
- PasswordField 密碼文本字段
- HiddenField 隱藏文本字段
- DateField 文本字段,值為 datetime.date 格式
- DateTimeField 文本字段,值為 datetime.datetime 格式
- IntegerField 文本字段,值為整數
- DecimalField 文本字段,值為 decim函數al.Decimal
- FloatField 文本字段,值為浮點數
- BooleanField 復選框,值為 True 和 False
- RadioField 一組單選框
- SelectField 下拉列表
- SelectMultipleField 下拉列表,可選擇多個值
- FileField 文件上傳字段
- SubmitField 表單提交按鈕
- FormField 把表單作為字段嵌入另一個表單
- FieldList 一組指定類型的字段
WTForms驗證函數
- Email 驗證電子郵件地址
- EqualTo 比較兩個字段的值;常用于要求輸入兩次密碼進行確認的情況
- IPAddress 驗證 IPv4 網絡地址
- Length 驗證輸入字符串的長度
- NumberRange 驗證輸入的值在數字范圍內
- Optional 無輸入值時跳過其他驗證函數
- Required 確保字段中有數據
- Regexp 使用正則表達式驗證輸入值
- URL 驗證 URL
- AnyOf 確保輸入值在可選值列表中
- NoneOf 確保輸入值不在可選值列表中
#### 4.3把表單渲染成HTML
我們可以通過參數form將對象NameForm傳入模板
當前我們已經使用HTML渲染出來了。如果對外觀不滿意,我們還可以傳入參數來優化HTML屬性。例如傳入一個id
<form method="POST"> {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name(id='my-text-field') }} {{ form.submit() }} </form>我們也可以快速渲染,直接使用bootstrap中的樣式來
{% import "bootstrap/wtf.html" as wtf %} {{ wtf.quick_form(form) }}4.4在視圖函數中處理表單
python腳本的視圖函數不僅要渲染表單,還得接收表單中的數據。
@app.route('/',methods=['GET','POST']) def index():name = None# 設置一個空的nameform = NameForm()# 實例化對象if form.validate_on_submit(): # 如果用戶提交數據了就返回True,否則Falsename = form.name.data# name 等于form.name的dataform.name.data = ''# 清空form.name.datareturn render_template('index.html',form=form,name=name)# 返回渲染html4.5重定向和用戶會話
刷新網頁的情況下會出現警告,POST請求的數據可能會丟失。程序可以把數據存儲在用戶會話中,在請求之間記住這些數據。用戶會話’session’
@app.route('/',methods=['POST','GET']) def index():name = 'haozhan'form = NameForm()if form.validate_on_submit():session['name'] = form.name.datareturn redirect(url_for('index'))render_template("index.html",name=session.get('name'),form=form)4.6flash消息
{% for message in get_flashed_messages() %} {{ message }} {% endfor %} if (session['name']=="admin"):flash('禁止')總結
- 上一篇: Android 应用统一字体设置 typ
- 下一篇: 投名狀观後感