1. 程式人生 > >十分鐘學會Flask

十分鐘學會Flask

什麼是Flask

  • Flask是一個基於Python並且依賴於Jinja2模板引擎和Werkzeug WSGI服務的一個微型框架
  • Flask中包含一個輕量級的web 伺服器主要用於在開發階段測試使用
  • Falsk使用MTV框架模式

MTV框架模式

  • M : Models , 模型層 , 主要負責根據資料庫建模
  • T : Templates , 模板層 ,處理使用者的顯示的內容的,如:html
  • V : Views ,檢視 , 處理與使用者互動的內容(請求和響應)

下面我們從Templates、Views和Models這三個部分來了解下Flask框架

Templates

Templates這部分主要講解以下幾個部分:

  • 過濾器
  • 標籤(for迴圈遍歷可迭代物件)
  • 巨集
  • 繼承
  • 自定義404/500等錯誤頁面

過濾器

語法:
{{變數|過濾器}}

Jinja2模板中常用的過濾器有:
capitalize     首字元變大寫,其他字元變小寫
lower          將值轉換為小寫字元
upper          將值轉換為大寫字元
title          將值中的每個單詞的首字元變大寫
trim           去掉值兩端的空格
複製程式碼

標籤

{% for 變數 in 列表|元組|字典 %}
{% endfor %}
for
標籤中的內建物件loop loop.index 獲取下標 loop.index0 從0開始的下標 loop.first True/False loop.last True/False 複製程式碼

巨集

下面是一個關於Flask中巨集的用法的例項:
<!-- 宣告巨集:接收一個字串作為引數,將引數放p中列印輸出 -->
{% macro showP(str) %}
    <h3>使用巨集顯示的內容:</h3>
    <p>{{str}}</p>
{% endmacro %}

<!-- 使用巨集 -->
<div>
    {% for
name in params.list %} {{showP(name)}} {% endfor %} </div> <!-- 引入外部的巨集 --> {% import 'macros.html' as ms %} {% for name in params.list %} {{ms.show_p(name)}} {% endfor %} 複製程式碼

繼承

父模板中:
{% block title %}
    父模板中的內容
{% endblock %}

子模板中:
{% extends '父模板.html' %}
{% block title %}
    子模板中的內容
{% endblock %}

子模板中的內容會覆蓋父模板中的內容
複製程式碼

自定義404/500等錯誤頁面

1.404 的錯誤處理
	@app.errorhandler(404)
	def page_not_fount(e):
		return render_template('404.html'),404
2.500 的錯誤處理
	@app.errorhandler(500)
	def internal_server_error(500):
		return render_template('500.html'),500
404.html 和 500.html 需要自定義
複製程式碼

Views

Views這部分主要講解以下幾個部分:

  • 路由
  • 請求方法
  • url反向解析
  • request物件
  • 響應response
  • 檔案上傳
  • cookies
  • session

路由

一:基本路由的配置:
#http://127.0.0.1:5000/
@app.route('/')
def index():
	return "xxx"

二:帶引數路由的配置:
1.基本帶引數的路由
@app.route('/show/<name>')
def show1(name):
	name:表示的就是位址列上傳遞的資料
	pass
2.指定引數型別的路由
@app.route('/show/<name>/<int:age>')
def show(name,age):
	name : 字串
	age : 整數
可選的引數型別為 int float path(字串,可以有斜槓/)

三:多個路由的配置:
@app.route('/地址1')
@app.route('/地址2')
....
def index():
	pass
複製程式碼

請求方法

在Flask中預設只能接收get請求,post請求無法接收,但是可以手動設定請求的接收方式。

下面的函式既能接收get請求又能接收post請求
@app.route('/xxx',methods=['POST','GET'])
def  xxx():
    pass
複製程式碼

url反向解析

正向解析:程式自動解析,根據@app.route()中的訪問路徑,來匹配處理函式
反向解析:通過檢視處理函式的名稱自動生成對應的訪問路徑

在Flask中要實現反向解析:
	url_for(funName,args)
		funName:要生成地址的函式名
		args:該地址中需要的引數
複製程式碼

request物件

request中的常用成員
	1.scheme:獲取請求方案(協議)
	2.method:獲取請求方式(重點,取值為 post 或 get)
	3.args : 獲取使用get請求方式提交過來的資料(重點)
	4.form : 獲取使用post請求方式提交過來的資料(重點)
	5.cookies : 獲取cookies中的相關資訊
	6.headers : 獲取請求訊息頭的相關資訊
	7.files : 獲取上傳的檔案
	8.path : 獲取請求的資源的具體路徑(不帶引數)
	9.full_path : 獲取完整的請求資源的具體路徑(帶引數)
	10.url : 獲取完整的請求地址,從協議開始
複製程式碼

響應response

響應有下面的三種方法:
1.返回響應模板(可帶上引數)
@app.route('/')
from flask import render_template
def index1():
    return render_template('xxx.html', params=locals())
    
2.構建響應物件,並返回
from flask import make_response
@app.route('/')
def index2():
    resp = make_response('響應內容')
    resp = make_response(render_template('xxx.html'))
    return resp
    
3.重定向
from flask import redirect
@app.route('/')
def index3():
    return redirect('/login')
複製程式碼

檔案上傳

html檔案:

<form action="/01-file" method="post" enctype="multipart/form-data">
    <p>
        使用者姓名: <input type="text" name="uname">
    </p>
    <p>
        使用者影象: <input type="file" name="uimg">
    </p>
    <p>
        <input type="submit" value="提交">
    </p>
</form>
複製程式碼

後臺程式碼:

@app.route('/01-file',methods=['GET','POST'])
def file_views():
    if request.method == 'GET':
        return render_template('01-file.html')
    else:
        #處理的上傳的檔案
        #1.得到上傳的檔案
        f = request.files['uimg']
        #2.將檔案儲存進指定的目錄處[相對路徑]
        # print('檔名稱:'+f.filename)
        # f.save('static/'+f.filename)

        #3.將檔案儲存進指定的目錄處[絕對路徑]
        #獲取當前檔案的所在目錄名
        basedir = os.path.dirname(__file__)
        #print('當前檔案所在目錄的絕對路徑:'+basedir)
        #獲取當前的時間拼成字串,再拼上副檔名
        ftime=datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")
        #獲取檔案的副檔名 (b04.jpg)
        ext = f.filename.split('.')[1]
        filename = ftime + "." + ext
        upload_path = os.path.join(basedir,'static/upload',filename)
        # print('完整的上傳路徑:'+upload_path)
        f.save(upload_path)
        return "Save OK"
複製程式碼

cookies

增:
    resp=make_response('儲存cookie成功')
    resp.set_cookie('uname','test',3600)
刪:
    響應物件.delete_cookie('key')
查詢:
    uname = request.cookies.get('key')
    request.cookies['key']
    request.cookies   # 拿到所有的cookies
    if 'key' in request.cookies:
        pass

複製程式碼

session

from flask import session
配置 SECRET_KEY:
      app.config['SECRET_KEY']="thisisarandomstring"
增:
    session['key'] = value
刪:
    del session['key']
查:
    value = session['key']
    value = session.get('key')

複製程式碼

Models

Models這部分主要講解以下幾個部分:

  • 資料庫連線和基本配置
  • 模型類的關係對映
  • 插入資料
  • 查詢資料

資料庫連線和基本配置

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# 為app指定資料庫的配置資訊
app.config['SQLALCHEMY_DATABASE_URI']='mysql://root:[email protected]:3306/flask'
#指定當檢視執行完畢後,自動提交資料庫操作
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True
# 建立 SQLAlchemy的資料庫例項
db = SQLAlchemy(app)
複製程式碼

模型類的關係對映

下面連結有詳細的講解這一部分: 模型類的關係對映

插入資料

#接收前端傳遞過來的資料
uname = request.form.get('uname')
uage = request.form.get('uage')
uemail = request.form.get('uemail')
#將資料構建成實體物件
user = Users(uname,uage,uemail)
#將資料儲存回資料庫
db.session.add(user)
# db.session.commit()
複製程式碼

查詢資料

  • 基於db.session進行查詢
  • 基於
基於db.session進行查詢
語法
db.sessin.query().過濾器函式().執行函式()
複製程式碼
基於 Models 類進行查詢
語法:
Models.query.查詢過濾器函式().查詢執行函式()
複製程式碼
過濾器函式
過濾器函式
作用:專門對資料進行篩選,返回部分行資料
1.filter()    按指定條件進行過濾(單表,多表,定值,不定值)
2.filter_by() 按等值條件進行過濾
3.limit()     按限制行數量獲取結果
4.order_by()  按指定列進行排序
5.group_by()  按指定條件進行分組

過濾器函式詳解:
過濾器函式詳解:
1.filter()
  注意:條件必須由 實體類.屬性 組成
  1.查詢年齡大於 30 的人的資訊
    db.session.query(Users).filter(Users.age>30).all()
  2.查詢id為1的人的資訊
    db.session.query(Users).filter(Users.id==1).first()
    注意:filter()做等值判斷時必須使用 == 
  3.查詢年齡大於30並且id大於1的使用者的資訊
    filter(條件1,條件2,...) : and
    db.session.query(Users).filter(Users.age>30,Users.id>1).all()
  4.查詢年齡大於30或者id為1的使用者的資訊
    查詢或者操作,需要使用or_()
    filter(or_(條件1,條件2))

    from sqlalchemy import or_
    db.session.query(Users).filter(or_(Users.age>30,Users.id==1)).all()
  5.查詢 email 中包含 'w' Users的資訊
    db.session.query(Users).filter(Users.email.like('%w%'))
  6.查詢 id 在 [2,4] 列表中的Users的資訊
    db.session.query(Users).filter(Users.id.in_([2,4])).all()
2.filter_by()
  注意:只能做等值判斷,不能做不等值
  查詢id為1的users的資訊
  db.session.query(Users).filter_by(id=1).first()
3.limit()
  1.獲取 users 表中的前2條資料
    db.session.query(Users).limit(2).all()
    select * from users limit 2
  2.獲取 users 表中過濾前3條資料後剩餘的前2條資料
    select * from users limit 3,2
    db.session.query(Users).limit(2).offset(3).all()
    
4.order_by()
  # 按照 id 倒序排序
  select * from users order by id desc;
  # 先按照年齡倒序排序,再按照id升序排序
  select * from users order by age desc,id asc;

  db.session.query(Users).order_by("age desc,id asc").all()
5.group_by()
  1.將 users 表中的資料按照 age 進行分組
    db.session.query(Users.age).group_by('age').all()
6.聚合函式
  1.查詢users表中所有人的平均年齡
    select avg(age) from users;

    from sqlalchemy import func
    db.session.query(func.avg(Users.age).label('avgAge')).all()
  2.users表中,按年齡分組,再查每組的年齡平均值
    select age,avg(age) from users group by age

    db.session.query(func.avg(Users.age)).group_by('age').all()

  聚合函式:
    1.func.avg() : 求平均值
    2.func.sum() : 求和
    3.func.max() : 求最大值
    4.func.min() : 求最小值
    5.func.count() : 求不為空的數量
複製程式碼
執行函式
查詢執行函式
目的:在query()的基礎上得到最終的資料
語法:db.session.query(Models).查詢執行函式()
1.all():以列表的方式返回query物件中所有的查詢資料
2.first():返回query物件中的第一個查詢結果,
  如果沒有結果,返回None
3.first_or_404():返回query物件中的第一個查詢結果,
  如果沒有結果的話則終止程式並響應404
4.count():返回query物件中的查詢結果的數量
複製程式碼