Flask基礎(常規)

1.Flask最核心的WerkZeug和Jinja2

使用Werkzeug來作路由分發(URL請求和視圖函數之間的對應關係)
使用Jinja2來渲染模板
複製代碼

2.Flask擴展包

Flask-SQLalchemy:操做數據庫;
Flask-migrate:管理遷移數據庫;
Flask-Mail:郵件;
Flask-WTF:表單;
Flask-script:插入腳本;
Flask-Login:認證用戶狀態;
Flask-RESTful:開發REST API的工具;
Flask-Bootstrap:集成前端Twitter Bootstrap框架;
Flask-Moment:本地化日期和時間;
複製代碼

3.Flask程序運行過程

客戶端發送http請求,web服務器使用WSGI協議,把來自客戶端的全部請求都交給Flask程序實例(WSGI是爲 Python 語言定義的Web服務器
和Web應用程序之間的一種簡單而通用的接口,它封裝了接受HTTP請求、解析HTTP請求、發送HTTP,響應等等的這些底層的代碼和操做,使開發
者能夠高效的編寫Web應用)
程序實例使用Werkzeug來作路由分發(URL請求和視圖函數之間的對應關係)。根據每一個URL請求,找到具體的視圖函數。 在Flask程序中,路由
的實現通常是經過程序實例的route裝飾器實現。route裝飾器內部會調用add_url_route()方法實現路由註冊調用視圖函數,獲取響應數據後,
把數據傳入HTML模板文件中,模板引擎負責渲染響應數據,而後由Flask返回響應數據給瀏覽器,最後瀏覽器處理返回的結果顯示給客戶端。
複製代碼

4.狀態碼,重定向(redirect),render_template(),url_for,flash

a.自定義狀態碼,在返回的響應的後邊
@app.route('/')
def hello_itcast():
    return 'hello itcast',500

b.重定向
@app.route('/')
def hello_itcast():
    return redirect("http://www.baidu.com")

c.url_for的用法
1.url_for()函數是以視圖函數名爲參數,返回對應的url
2.加載靜態參數
  <link rel='stylesheet' href="{{ url_for('static',filename='css/index.css')}}">
  <li>{{ book.name }} <a href="{{ url_for('delete_book',book_id=book.id) }}">刪除</a></li>
複製代碼

5.錯誤頁面的自定義以及模板上下文處理函數

a.自定義404頁面(捕獲異常)
@app.errorhandler(404)  # 傳入要處理的錯誤代碼
def page_not_found(e):  # 接受異常對象做爲參數
    user = User.query.first()
    return render_template('404.html', user=user), 404  # 返回模板和狀態碼
b.模板上下文處理函數(因爲多個模板都須要用到user這個變量,直接在這個函數裏面取出)
@app.context_processor
def inject_user():  # 函數名能夠隨意修改
    user = User.query.first()
    return dict(user=user)  # 須要返回字典,等同於return {'user': user}
複製代碼

6.url的自定義

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
複製代碼

7.abort函數的使用

若是在視圖函數執行過程當中,出現了異常錯誤,咱們可使用abort函數當即終止視圖函數的執行,若是abort函數被觸發,其後面的語句將不會執行
from flask import Flask,abort
@app.route('/')
def hello_itcast():
    abort(404)
    return 'hello itcast',999

注意abort裏面的狀態碼必須就是HTTP狀態碼,不能本身隨便寫。常見狀態碼以下:
狀態代碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別:
1xx:指示信息--表示請求已接收,繼續處理
2xx:成功--表示請求已被成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操做
4xx:客戶端錯誤--請求有語法錯誤或請求沒法實現
5xx:服務器端錯誤--服務器未能實現合法的請求
常見狀態碼:
複製代碼

8.請求鉤子

Flask的請求鉤子指的是在執行視圖函數先後執行的一些函數,咱們能夠在這些函數裏面作一些操做。Flask利用裝飾器給咱們提供了四種鉤子函數。css

before_first_request:在處理第一個請求前執行。好比連接數據庫操做 before_request:在每次請求前執行。好比權限校驗 after_request:每次請求以後調用,前提是沒有未處理的異常拋出 teardown_request:每次請求以後調用,即便有未處理的異常拋出html

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    print('視圖函數執行')
    return 'index page'


# 在第一次請求以前運行.
@app.before_first_request
def before_first_request():
    print('before_first_request')


# 在每一次請求前都會執行
@app.before_request
def before_request():
    print('before_request')


# 在請求以後運行
@app.after_request
def after_request(response):
    # response: 就是前面的請求處理完畢以後, 返回的響應數據,前提是視圖函數沒有出現異常
    # 若是須要對響應作額外處理,能夠再這裏進行
    # json.dumps 配置請求鉤子
    # response.headers["Content-Type"] = "application/json"
    print('after_request')
    return response


# 不管視圖函數是否出現異常,每一次請求以後都會調用,會接受一個參數,參數是服務器出現的錯誤信息
@app.teardown_request
def teardown_request(error):
    print('teardown_request: error %s' % error)


if __name__ == '__main__':
    app.run(debug=True)
複製代碼

9.request對象經常使用屬性

10.文件上傳

上傳文件也是咱們常常用到的功能,前端上傳一張文件,而後後端處理保存到服務器上。 文件這種類型屬於多媒體類型資源。前端form表單裏面須要加enctype="multipart/form-data"。咱們新建一個名upload.html模板 模板裏面寫以下代碼:前端

<form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="上傳">
</form>
複製代碼

upload.py文件代碼以下:(同級目錄下建立media文件夾)web

from flask import Flask, request,render_template,redirect,url_for
from werkzeug.utils import secure_filename
import os
from flask import send_from_directory


app = Flask(__name__)

UPLOAD_FOLDER = 'media'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 判斷上傳的文件是不是容許的後綴
def allowed_file(filename):
    return "." in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS



@app.route('/upload',methods=['GET','POST'])
def upload():
    '''文件上傳'''
    if request.method == 'GET':
        return render_template('upload.html')

    else:
        print(request.files)
        print(type(request.files))
        if "file" not in request.files:
            return redirect(request.url)

        file = request.files.get('file')  # 獲取文件
        print(type(file))

        if file.filename == '':
            return redirect(request.url)

        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)  # 用這個函數肯定文件名稱是不是安全 (注意:中文不能識別)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))  # 保存文件
            return redirect(url_for('show',filename=filename))

# 展現圖片
@app.route('/show/<filename>')
def show(filename):
    # send_from_directory能夠從目錄加載文件
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
複製代碼

11.Flask框架上下文

參考:https://juejin.im/post/5ccd3670f265da0373719711
複製代碼

12.Response

視圖在接收HttpRequest並處理後,必須返回HttpResponse對象, 可使用make_response()函數而後再進行修改 示例代碼:數據庫

from flask import Flask, render_template, make_response

app = Flask(__name__)


@app.route('/setcookie', methods=['GET', 'POST'])  # 支持get、post請求
def setcookie():  # 視圖函數
    resp = make_response(render_template('cookie.html'))  # 顯式轉換成HttpResponse對象
    return resp

app.config['DEBUG'] = True

if __name__ == '__main__':
    # 0.0.0.0表明任何能表明這臺機器的地址均可以訪問
    app.run(host='0.0.0.0', port=5000)  # 運行程序
複製代碼

13.自定義響應信息

自定義響應信息,能夠用make_response函數。make_response(),至關於Django中的HttpResponse,效果是同樣的。json

from flask import Flask, abort, Response, make_response

app = Flask(__name__)


@app.route('/')
def index():
    # return ('自定義響應信息', 502, {"name": "xiaosong", "age": 12})

    # 能夠不加括號,會自動組裝成元組
    # return '自定義響應信息', 502, {"name": "xiaosong", "age": 12}

    # 自定義狀態碼 能夠加上描述信息
    # return '自定義響應信息', '520 love error', {"name": "xiaosong", "age": 12}
    resp = make_response()
    resp.headers['name'] = 'xiaosong'
    resp.status = '520 love error'
    return resp


if __name__ == '__main__':
    # 0.0.0.0表明任何能表明這臺機器的地址均可以訪問
    app.run(host='0.0.0.0', port=5000, debug=True)  # 運行程序

複製代碼

使用jsonfy返回響應信息和直接json.dumps(data)返回信息是不一樣的,表如今響應頭中的Content-Type字段flask

jsonify:後端

Content-Type: application/json瀏覽器

json.dumps(data):安全

Content-Type: text/html; charset=utf-8

相關文章
相關標籤/搜索