Flask知识点回顾以及重点内容
1.?HTTP通信與Web框架
1.1 流程
客戶端將請求打包成HTTP的請求報文(HTTP協議格式的請求數據)
采用TCP傳輸發送給服務器端
服務器接收到請求報文后按照HTTP協議進行解析
服務器根據解析后獲知的客戶端請求進行邏輯執行
服務器將執行后的結果封裝成HTTP的響應報文(HTTP協議格式的響應數據)
采用剛才的TCP連接將響應報文發送給客戶端
客戶端按照HTTP協議解析響應報文獲取結果數據
1.2 細節
客戶端不一定是瀏覽器,也可以是PC軟件、手機APP、程序
根據服務器端的工作,將其分為兩部分:
服務器:與客戶端進行tcp通信,接收、解析、打包、發送http格式數據
業務程序:根據解析后的請求數據執行邏輯處理,形成要返回的數據交給服務器
服務器與Python業務程序的配合使用WSGI協議
1.3 Web框架
能夠被服務器調用起來,根據客戶端的不同請求執行不同的邏輯處理形成要返回的數據的 程序
?
核心:實現路由和視圖(業務邏輯處理)
?
1.4 框架的輕重
重量級的框架:為方便業務程序的開發,提供了豐富的工具、組件,如Django
?
輕量級的框架:只提供Web框架的核心功能,自由、靈活、高度定制,如Flask、Tornado
webpy
?
1.5 明確Web開發的任務
視圖開發:根據客戶端請求實現業務邏輯(視圖)編寫
模板、數據庫等其他的都是為了幫助視圖開發,不是必備的
?
2.?認識Flask
2.1 簡介
Flask誕生于2010年,是Armin ronacher(人名)用Python語言基于Werkzeug工具箱編寫的輕量級Web開發框架。它主要面向需求簡單的小應用。
?
Flask本身相當于一個內核,其他幾乎所有的功能都要用到擴展(郵件擴展Flask-Mail,用戶認證Flask-Login),都需要用第三方的擴展來實現。比如可以用Flask-extension加入ORM、窗體驗證工具,文件上傳、身份驗證等。Flask沒有默認使用的數據庫,你可以選擇MySQL,也可以用NoSQL。其 WSGI 工具箱采用 Werkzeug(路由模塊) ,模板引擎則使用 Jinja2 。
?
可以說Flask框架的核心就是Werkzeug和Jinja2。
?
Python最出名的框架要數Django,此外還有Flask、Tornado等框架。雖然Flask不是最出名的框架,但是Flask應該算是最靈活的框架之一,這也是Flask受到廣大開發者喜愛的原因。
2.2 與Django對比
django提供了:
django-admin快速創建項目工程目錄
manage.py 管理項目工程
orm模型(數據庫抽象層)
admin后臺管理站點
緩存機制
文件存儲系統
用戶認證系統
?
而這些,flask都沒有,都需要擴展包來提供
2.3 Flask擴展包:
Flask-SQLalchemy:操作數據庫;
Flask-migrate:管理遷移數據庫;
Flask-Mail:郵件;
Flask-WTF:表單;
Flask-script:插入腳本;
Flask-Login:認證用戶狀態;
Flask-RESTful:開發REST API的工具;
Flask-Bootstrap:集成前端Twitter Bootstrap框架;
Flask-Moment:本地化日期和時間;
2.4 Flask文檔
中文文檔: http://docs.jinkan.org/docs/flask/
英文文檔: http://flask.pocoo.org/docs/0.11/
3.?創建虛擬環境
虛擬環境是一個互相隔離的目錄
1.?mkvirtualenv flask_py2
2.?pip install flask==0.10.1
?
pip freeze > requirements.txt
pip install –r requirements.txt
4.?Flask的Hello world程序
# coding:utf-8
?
# 導入Flask類
from flask import Flask
?
#Flask類接收一個參數__name__
app = Flask(__name__)
?
# 裝飾器的作用是將路由映射到視圖函數index
@app.route('/')
def index():
????return 'Hello World'
?
# Flask應用程序實例的run方法啟動WEB服務器
if __name__ == '__main__':
????app.run()
?
4.1 Flask創建app對象
4.1.1 初始化參數
import_name: 導入路徑(尋找靜態目錄與模板目錄位置的參數)
static_url_path:
static_folder: 默認‘static’
template_folder: 默認‘templates’
4.1.2 配置參數
app.config.from_pyfile(“yourconfig.cfg”) 或
app.config.from_object()
app.config[“DEBUG”] = True
4.1.3 在視圖讀取配置參數
app.config.get() ?或者 current_app.config.get()
4.1.4 app.run的參數
app.run(host=”0.0.0.0”, port=5000, debug=True)
4.2 路由
4.2.1 app.url_map 查看所有路由
?
4.2.2 同一路由裝飾多個視圖函數
?
4.2.3 同一視圖多個路由裝飾器
?
4.2.4 利用methods限制訪問方式
@app.route('/sample', methods=['GET', 'POST'])
4.2.5 使用url_for進行反解析
?
4.2.5 動態路由
# 路由傳遞的參數默認當做string處理,這里指定int,尖括號中冒號后面的內容是動態的
@app.route('/user/<int:id>')
def hello_itcast(id):
????return 'hello itcast %d' %id
?
4.2.5 自定義轉換器
from flask import Flask
from werkzeug.routing import BaseConverter
?
class Regex_url(BaseConverter):
????def __init__(self,url_map,*args):
????????super(Regex_url,self).__init__(url_map)
????????self.regex = args[0]
?
app = Flask(__name__)
app.url_map.converters['re'] = Regex_url
?
@app.route('/user/<re("[a-z]{3}"):id>')
def hello_itcast(id):
????return 'hello %s' %id
4.3 獲取請求參數
from flask import request
?
就是 Flask 中表示當前請求的 request 對象,request對象中保存了一次HTTP請求的一切信息。
?
4.3.1 上傳文件
已上傳的文件存儲在內存或是文件系統中一個臨時的位置。你可以通過請求對象的 files 屬性訪問它們。每個上傳的文件都會存儲在這個字典里。它表現近乎為一個標準的 Python file 對象,但它還有一個 save() 方法,這個方法允許你把文件保存到服務器的文件系統上。這里是一個用它保存文件的例子:
?
from flask import request
?
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
????if request.method == 'POST':
????????f = request.files['the_file']
????????f.save('/var/www/uploads/uploaded_file.txt')
????...
如果你想知道上傳前文件在客戶端的文件名是什么,你可以訪問 filename 屬性。但請記住, 永遠不要信任這個值,這個值是可以偽造的。如果你要把文件按客戶端提供的文件名存儲在服務器上,那么請把它傳遞給 Werkzeug 提供的 secure_filename() 函數:
from flask import request
from werkzeug import secure_filename
?
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
????if request.method == 'POST':
????????f = request.files['the_file']
????????f.save('/var/www/uploads/' + secure_filename(f.filename))
????...
4.4 abort函數與自定義異常處理
4.4.1 abort函數
from flask import abort
abort(404)
4.4.2 自定義異常處理
@app.errorhandler(404)
def error(e):
????return '您請求的頁面不存在了,請確認后再次訪問!%s'%e
?
4.5 返回的響應數據
4.5.1 元組
可以返回一個元組,這樣的元組必須是 (response, status, headers)?的形式,且至少包含一個元素。 status 值會覆蓋狀態代碼, headers 可以是一個列表或字典,作為額外的消息標頭值。[(key, value),()] ??{“key”:”value”,…}
?
4.5.2 make_response
resp = make_response(“”)
resp.headers[“sample”] =?“value”
resp.status = “404 not found”
?
4.6 使用jsonify返回json數據
json.dumps() ?json.loads()
jsonify(key=value, k1=v1)
4.5 重定向
from flask import redirect
?
4.6 設置和讀取cookie
resp = make_response()
?
resp.set_cookie(key, value=’’, max_age=None)
?
resp.delete_cookie(key)
?
request.cookies.get()
4.7 session
from flask import session
?
需要設置secret_key
?
session[key] = val
value = session.get(key)
?
4.8 請求上下文與應用上下文
?
請求上下文(request context)??
request和session都屬于請求上下文對象。
?
應用上下文(application context)
current_app和g都屬于應用上下文對象。
?
current_app:表示當前運行程序文件的程序實例。
g:處理請求時,用于臨時存儲的對象,每次請求都會重設這個變量。
?
4.9 請求鉤子 hook
請求鉤子是通過裝飾器的形式實現,Flask支持如下四種請求鉤子:
?
before_first_request:在處理第一個請求前運行。
?
@app.before_first_request
?
before_request:在每次請求前運行。
?
after_request(response):如果沒有未處理的異常拋出,在每次請求后運行。
?
teardown_request(response):在每次請求后運行,即使有未處理的異常拋出。
?
5.?Flask-Script擴展命令行
pip install Flask-Script
?
runserver –h ip地址 –p端口號
shell
?
from flask import Flask
from flask_script import Manager
?
app = Flask(__name__)
?
manager = Manager(app)
?
@app.route('/')
def index():
????return '床前明月光'
?
if __name__ == "__main__":
????manager.run() ???...
6.?Jinja2模板
6.1 基本流程
<!DOCTYPE html>
<html lang="en">
<head>
????<meta charset="UTF-8">
????<title>Template</title>
</head>
<body>
????<h1>hello {{ name }}</h1>
</body>
</html>
?
@app.route("/")
def index():
????return render_template("index.html", name="python",…)
?
使用flask 中的render_template渲染模板
6.2 變量
<p>{{mydict['key']}}</p>
?
<p>{{mydict.key}}</p>
?
<p>{{mylist[1]}}</p>
?
<p>{{mylist[myvariable]}}</p>
from flask import Flask,render_template
app = Flask(__name__)
?
@app.route('/')
def index():
????mydict = {'key':'silence is gold'}
????mylist = ['Speech', 'is','silver']
????myintvar = 0
?
????return render_template('vars.html',
???????????????????????????mydict=mydict,
???????????????????????????mylist=mylist,
???????????????????????????myintvar=myintvar
???????????????????????????)
if __name__ == '__main__':
????app.run(debug=True)
6.3 過濾器
6.3.1 字符串過濾器
safe:禁用轉義;
??<p>{{ '<em>hello</em>' | safe }}</p>
?
capitalize:把變量值的首字母轉成大寫,其余字母轉小寫;
??<p>{{ 'hello' | capitalize }}</p>
?
lower:把值轉成小寫;
??<p>{{ 'HELLO' | lower }}</p>
?
upper:把值轉成大寫;
??<p>{{ 'hello' | upper }}</p>
?
title:把值中的每個單詞的首字母都轉成大寫;
??<p>{{ 'hello' | title }}</p>
?
trim:把值的首尾空格去掉;
??<p>{{ ' hello world ' | trim }}</p>
?
reverse:字符串反轉;
??<p>{{ 'olleh' | reverse }}</p>
?
format:格式化輸出;
??<p>{{ '%s is %d' | format('name',17) }}</p>
?
striptags:渲染之前把值中所有的HTML標簽都刪掉;
??<p>{{ '<em>hello</em>' | striptags }}</p>
?
6.3.2 支持鏈式使用過濾器
<p>{{ “?hello world ?“?| trim | upper }}</p>
6.3.3 列表過濾器
first:取第一個元素
??<p>{{ [1,2,3,4,5,6] | first }}</p>
?
last:取最后一個元素
??<p>{{ [1,2,3,4,5,6] | last }}</p>
?
length:獲取列表長度
??<p>{{ [1,2,3,4,5,6] | length }}</p>
?
sum:列表求和
??<p>{{ [1,2,3,4,5,6] | sum }}</p>
?
sort:列表排序
??<p>{{ [6,2,3,1,5,4] | sort }}</p>
?
6.3.4 自定義過濾器
自定義的過濾器名稱如果和內置的過濾器重名,會覆蓋內置的過濾器。
?
方式一:
通過 add_template_filter (過濾器函數, 模板中使用的過濾器名字)
def filter_double_sort(ls):
????return ls[::2]
app.add_template_filter(filter_double_sort,'double_2')
?
方式二:
通過裝飾器 ?app.template_filter (模板中使用的裝飾器名字)
@app.template_filter('db3')
def filter_double_sort(ls):
????return ls[::-3]
6.4 表單
使用Flask-WTF表單擴展,可以幫助進行CSRF驗證,幫助我們快速定義表單模板,而且可以幫助我們在視圖中驗證表的數據
?
pip install Flask-WTF
6.4.1 不使用Flask-WTF擴展時,表單需要自己處理
#模板文件
<form method='post'>
????<input type="text" name="username" placeholder='Username'>
<input type="password" name="password" placeholder='password'>
????<input type="submit">
</form>
from flask import Flask,render_template,request
?
@app.route('/login',methods=['GET','POST'])
def login():
????if request.method == 'POST':
????????username = request.form['username']
????????password = request.form['password']
????????print username,password
???? return “success”
else:
return render_template(“login.html”)
6.4.2 使用Flask-WTF擴展
需要設置 SECRET_KEY 的配置參數
?
模板頁:
<form method="post">
????????#設置csrf_token
????????{{ form.csrf_token() }}
????????{{ form.us.label }}
????????<p>{{ form.us }}</p>
????????{{ form.ps.label }}
????????<p>{{ form.ps }}</p>
????????{{ form.ps2.label }}
????????<p>{{ form.ps2 }}</p>
????????<p>{{ form.submit() }}</p>
????????{% for x in get_flashed_messages() %}
????????????{{ x }}
????????{% endfor %}
?</form>
?
視圖函數
#coding=utf-8
from flask import Flask,render_template, redirect,url_for,session,request,flash
?
#導入wtf擴展的表單類
from flask_wtf import FlaskForm
#導入自定義表單需要的字段
from wtforms import SubmitField,StringField,PasswordField
#導入wtf擴展提供的表單驗證器
from wtforms.validators import DataRequired,EqualTo
app = Flask(__name__)
app.config['SECRET_KEY']='1'
?
#自定義表單類,文本字段、密碼字段、提交按鈕
class Login(Flask Form):
????us = StringField(label=u'用戶:',validators=[DataRequired()])
????ps = PasswordField(label=u'密碼',validators=[DataRequired(),EqualTo('ps2','err')])
????ps2 = PasswordField(label=u'確認密碼',validators=[DataRequired()])
????submit = SubmitField(u'提交')
?
#定義根路由視圖函數,生成表單對象,獲取表單數據,進行表單數據驗證
@app.route('/',methods=['GET','POST'])
def index():
????form = Login()
????if form.validate_on_submit():
????????name = form.us.data
????????pswd = form.ps.data
????????pswd2 = form.ps2.data
????????print name,pswd,pswd2
????????return redirect(url_for('login'))
????else:
????????if request.method=='POST':
flash(u'信息有誤,請重新輸入!')
?
????return render_template('index.html',form=form)
if __name__ == '__main__':
????app.run(debug=True)
?
6.5 控制語句
6.5.1 if語句
{% if %} {% endif %}
6.5.2 for語句
{% for item in samples %} {% endfor %}
?
6.6 宏
類似于python中的函數,宏的作用就是在模板中重復利用代碼,避免代碼冗余。
?
6.6.1 不帶參數宏的定義與使用
定義:
{% macro input() %}
??<input type="text"
?????????name="username"
?????????value=""
?????????size="30"/>
{% endmacro %}
?
使用
{{ input() }}
?
6.6.2 帶參數宏的定義與使用
定義
{% macro input(name,value='',type='text',size=20) %}
????<input type="{{ type }}"
???????????name="{{ name }}"
???????????value="{{ value }}"
???????????size="{{ size }}"/>
{% endmacro %}
?
使用
{{ input(value='name',type='password',size=40)}}
?
6.6.3 將宏單獨封裝在html文件中
?
文件名可以自定義macro.html
?
{% macro input() %}
?
????<input type="text" name="username" placeholde="Username">
????<input type="password" name="password" placeholde="Password">
????<input type="submit">
{% endmacro %}
?
在其它模板文件中先導入,再調用
?
{% import 'macro.html' as func %}
{{ func.input() }}
?
6.4 模板繼承
extend
6.5 模板包含
include
?
6.6 flask在模板中使用特殊變量和方法
6.6.1 config
?
6.6.2 request
?
6.6.3 url_for
?
?
總結
以上是生活随笔為你收集整理的Flask知识点回顾以及重点内容的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学生管理系统代码赏析
- 下一篇: 评论数据获取、词频统计、词云图