Flask框架入門(一)


  Flask誕生於2010年,是Armin ronacher(人名)用 Python 語言基於 Werkzeug 工具箱編寫的輕量級Web開發框架。
  Flask 本身相當於一個內核,其他幾乎所有的功能都要用到擴展(郵件擴展Flask-Mail,用戶認證Flask-Login,數據庫Flask-SQLAlchemy),都需要用第三方的擴展來實現。比如可以用 Flask 擴展加入ORM、窗體驗證工具,文件上傳、身份驗證等。Flask 沒有默認使用的數據庫,你可以選擇 MySQL,也可以用 NoSQL。其 WSGI 工具箱采用 Werkzeug(路由模塊),模板引擎則使用 Jinja2。這兩個也是 Flask 框架的核心。

准備

mkvirtualenv flask_demo -p python3

安裝

pip install flask==0.12.4

一 .創建Flask項目

Flask不同於Django,不會提供任何自動的操作,所以需要手動創建項目目錄,需要手動創建啟動項目的管理文件

例如,創建項目目錄flaskdemo,在目錄中創建manage.py。在pycharm中打開項目並指定上面創建的虛擬環境

1 form flask import Flask
2 app = Flask(__name__)
3 
4 @app.route('/')
5 def index():
6     return 'Hello World'
7 
8 if __name__ == '__main__':
9     app.run

代碼分析:

 1 #導入Flask類
 2 
 3 """
 4 import_name      Flask程序所在的包(模塊),傳 __name__ 就可以
 5                          其可以決定 Flask 在訪問靜態文件時查找的路徑
 6 static_path         靜態文件訪問路徑(不推薦使用,使用 static_url_path 代替)
 7 static_url_path   靜態文件訪問路徑,可以不傳,默認為:/ + static_folder
 8 static_folder       靜態文件存儲的文件夾,可以不傳,默認為 static
 9 template_folder  模板文件存儲的文件夾,可以不傳,默認為 templates
10                                   
11 """     
12 app = Flask(__name__)                       
 1 #加載項目配置
 2 #配置類
 3 class Config(object)
 4     DEBUG = True
 5     SECRET_KEY = "aaabbbbbddddeeeeb"
 6 
 7 app.config.from_object(Config)
 8 
 9 
10 
11 
12 #指定服務器IP和端口
13 app.run(host="0.0.0.0",port=5000,debug = True)

二.路由的基本定義

1 #指定訪問路徑為demo1
2 @app.route('/demo1')
3 def demo1():
4     return 'demo1'

路由可以設置傳遞參數,2種方式

 1 # 路由傳遞參數[沒有限定類型]
 2 @app.route('/user/<user_id>')
 3 def user_info(user_id):
 4     return 'hello %s' % user_id
 5 
 6 
 7 # 路由傳遞參數[限定數據類型]
 8 @app.route('/user/<int:user_id>')
 9 def user_info(user_id):
10     return 'hello %d' % user_id

路由限定請求方式

1 def demo2():
2     # 直接從請求中取到請求方式並返回
3     return request.method

三.正則匹配路由

  在 web 開發中,可能會出現限制用戶訪問規則的場景,那么這個時候就需要用到正則匹配,根據自己的規則去限定請求參數再進行訪問

具體實現步驟為:

  • 導入轉換器基類:在 Flask 中,所有的路由的匹配規則都是使用轉換器對象進行記錄
  • 自定義轉換器:自定義類繼承於轉換器基類
  • 添加轉換器到默認的轉換器字典中
  • 使用自定義轉換器實現自定義匹配規則

四.代碼實現

  > 導入轉換器基類

from werkzeug.routing import BaseConverter

  > 自定義轉換器

1 # 自定義正則轉換器
2 from werkzeug.routing import BaseConverter
3 class RegexConverter(BaseConverter):
4     def __init__(self,url_map,*args):
5         super(RegexConverter, self).__init__(url_map)
6         # 正則參數
7         self.regex = args[0]

  > 添加轉換器到默認的轉換器字典中,並指定轉換器使用時名字為: re

1 # 將自定義轉換器添加到轉換器字典中,並指定轉換器使用時名字為: re
2 app.url_map.converters['re'] = RegexConverter

  > 使用轉換器去實現自定義匹配規則

    >> 當前此處定義的規則是 :手機號

1 # 正則匹配路由
2 @app.route("/login/<re('1\d{10}'):mobile>")
3 def login(mobile):
4     return mobile

五.系統自帶轉換器

1 DEFAULT_CONVERTERS = {
2     'default':          UnicodeConverter,
3     'path':             PathConverter,
4     'string':           UnicodeConverter,
5     'any':              AnyConverter,
6     'int':              IntegerConverter,
7     'float':            FloatConverter,
8     'uuid':             UUIDConverter,
9 }

系統自帶的轉換器具體使用方式在每種轉換器的注釋代碼中有寫,請留意每種轉換器初始化的參數。

 1 from flask import Flask
 2 # 新增一個配置文件,在配置文件中設置配置信息
 3 from config import Config
 4 from flask import request
 5 # from collections import OrderedDict  # 有序字典
 6 
 7 app = Flask(__name__)
 8 
 9 # 調用app.config加載配置
10 app.config.from_object(Config)
11 
12 
13 from werkzeug.routing import BaseConverter
14 
15 class RegexConverter(BaseConverter):
16     def __init__(self,url_map,*args):
17         super(RegexConverter, self).__init__(url_map)
18         # 正則參數
19         self.regex = args[0]
20 
21 # converter["路由轉換器名稱"] = 實現路由轉換功能的自定義類
22 app.url_map.converters['re'] = RegexConverter
23 # 綁定路由
24 @app.route("/")
25 def index():
26     return "hello flask"
27 
28 
29 # 默認情況下,路由使用的就是關鍵字參數,也叫"命名路由"
30 # router(路由地址, http請求方式 )
31 @app.route("/list/<int:page>/<string:content>",methods=["GET","POST"])
32 def mylist(content,page):
33     return "第%s頁<br>內容:%s" % (page,content)
34 
35 # 正則匹配路由
36 @app.route("/login/<re('1\d{10}'):mobile>")
37 def login(mobile):
38     return mobile

六.Http的請求與響應

  > 請求

    .request: flask中代表當前請求的 request對象

    .作用: 在視圖函數中取出本次請求數據

    .導入: from flask import request

        常用的屬性如下:

屬性 說明 類型
data 記錄請求的數據,並轉換為字符串 *
form 記錄請求中的表單數據 MultiDict
args 記錄請求中的查詢參數 MultiDict
cookies 記錄請求中的cookie信息 Dict
headers 記錄請求中的請求頭 EnvironHeaders
method 記錄請求使用的HTTP方法 GET/POST
url 記錄請求的URL地址 string
files 記錄請求上傳的文件 *
json 記錄請求的json數據 json

獲取請求中查詢字符串

http://127.0.0.1:5000/demo1?a=10

 1 """獲取客戶端的請求"""
 2 @app.route("/request")
 3 def req1():
 4     """獲取查詢字符串"""
 5     query_string = request.args
 6     print(query_string)
 7     # 瀏覽器輸入 http://127.0.0.1:5000/request?a=1&b=2
 8     """打印效果: ImmutableMultiDict([('a', '1'), ('b', '2')])"""
 9 
10     # 獲取一個參數的一個值
11     http://127.0.0.1:5000/request?username=abcd
12     username = request.args.get("username")
13     # print(username)
14     """打印效果: abcd  """
15 
16     # 獲取一個參數的多個值
17     # http://127.0.0.1:5000/request?username=xiaoming&love=吹牛&love=睡覺
18     love = request.args.getlist("love")
19     # print(love)
20     """打印效果: ['吹牛', '睡覺']"""
21 
22 
23     # 把傳遞過來的數據抓換成原生的字典
24     data = request.args.to_dict()
25     # print(data)
26     """打印效果:{'username': 'xiaoming', 'love': '吹牛'} """
27 
28     return "ok"
29 
30 @app.route("/request2",methods=["POST"])
31 def req2():
32     """獲取post數據和請求頭"""
33     # 必須傳 json 格式的數據
34     # print( request.data )
35     # """打印結果:
36     # b'{\n\t"username":"xiaoming",\n\t"age":18,\n\t"sex":1\n}'
37     # """
38     # 方式一
39     # import json
40     # from flask import json
41     # data = json.loads(request.data)
42     # print(data)
43     # """打印結果:
44     # {'username': 'xiaoming', 'age': 18, 'sex': 1}
45     #方式二 
46     print(request.json)
47     # """打印結果:
48     # {'username': 'xiaoming', 'age': 18, 'sex': 1}
49     # """
50     #
51     # """獲取請求行數據"""
52     # print( request.headers )
53     # print( request.headers.to_list() )
54 
55 
56     """獲取上傳文件"""
57     print( request.files )
58     print( request.files.get("avatar") )
59     """打印效果: 
60     ImmutableMultiDict([('avatar', <FileStorage: 'avatar.png' ('image/png')>)])
61     <FileStorage: 'avatar.png' ('image/png')>
62     """
63 
64     return "ok"
65 
66 if __name__ == '__main__':
67     app.run()
獲取客戶端請求

響應

flask默認支持2種響應方式:

  • 數據響應:
    默認響應html文本,也可以返回 JSON格式
  • 頁面響應:
    重定向 url_for

響應的時候,flask也支持自定義http響應狀態碼

響應html文本

1 @app.route("/")
2 def index():
3     # [默認支持]響應html文本
4     return "<img src='http://flask.pocoo.org/static/logo.png'>"

 

返回JSON數據

在 Flask 中可以直接使用 jsonify 生成一個 JSON 的響應

 1 from flask import Flask, request, jsonify
 2 
 3 @app.route("/")
 4 def index():
 5     # 也可以響應json格式代碼
 6     data = [
 7         {"id":1,"username":"liulaoshi","age":18},
 8         {"id":2,"username":"liulaoshi","age":17},
 9         {"id":3,"username":"liulaoshi","age":16},
10         {"id":4,"username":"liulaoshi","age":15},
11     ]
12     return jsonify(data)

flask中返回json 數據,都是flask的jsonify方法返回就可以了.

重定向

重定向到百度頁面

1 # 頁面跳轉響應
2 from flask import Flask, request, jsonify, redirect
3 @app.route("/user")
4 def user():
5     # 頁面跳轉 redirect函數就是response對象的頁面跳轉的封裝
6     # Location: http://www.baidu.com
7     return redirect("http://www.baidu.com")

 

重定向到自己寫的視圖函數

可以直接填寫自己 url 路徑

也可以使用 url_for 生成指定視圖函數所對應的 url

 1 # 內容響應
 2 @app.route("/")
 3 def index():
 4     # [默認支持]響應html文本
 5     # return "<img src='http://flask.pocoo.org/static/logo.png'>"
 6 
 7     # 也可以響應json格式代碼
 8     data = [
 9         {"id":1,"username":"liulaoshi","age":18},
10         {"id":2,"username":"liulaoshi","age":17},
11         {"id":3,"username":"liulaoshi","age":16},
12         {"id":4,"username":"liulaoshi","age":15},
13     ]
14     return jsonify(data)
15 
16 #使用url_for可以實現視圖方法之間的內部跳轉
17 # url_for("視圖方法名")
18 from flask import Flask, request, jsonify, redirect, url_for
19 @app.route("/login")
20 def login():
21     return redirect( url_for("index") )

重定向到帶有參數的視圖函數

在 url_for 函數中傳入參數

 1 # 路由傳遞參數
 2 @app.route('/user/<user_id>')
 3 def user_info(user_id):
 4     return 'hello %s' % user_id
 5 
 6 # 重定向
 7 @app.route('/demo4')
 8 def demo4():
 9     # 使用 url_for 生成指定視圖函數所對應的 url
10     return redirect(url_for('user_info', user_id=100))

自定義狀態碼

在 Flask 中,可以很方便的返回自定義狀態碼,以實現不符合 http 協議的狀態碼,例如:status code: 666

1 @app.route('/demo4')
2 def demo4():
3     return '狀態碼為 666', 400

三、會話控制

所謂的會話,就是用戶和瀏覽器中網站之間一次交互過程.

會話的開始是在用戶打開瀏覽器以后第一次訪問網站.

會話的結束時在用戶關閉瀏覽器以后.

因為 http 是一種無狀態協議,瀏覽器請求服務器是無狀態的。

無狀態:指一次用戶請求時,瀏覽器、服務器無法知道之前這個用戶做過什么,每次請求都是一次新的請求。

無狀態原因:瀏覽器與服務器是使用 socket 套接字進行通信的,服務器將請求結果返回給瀏覽器之后,會關閉當前的 socket 連接,而且服務器也會在處理頁面完畢之后銷毀頁面對象。

有時需要保持下來用戶瀏覽的狀態,比如用戶是否登錄過,瀏覽過哪些商品等

實現狀態保持主要有兩種方式:

  • 在客戶端存儲信息使用Cookie,本地存儲,token[jwt,oauth]
  • 在服務器端存儲信息使用Session,redis

四、cookie

Cookie是由服務器端生成,發送給客戶端瀏覽器,瀏覽器會將Cookie的key/value保存,下次請求同一網站時就發送該Cookie給服務器(前提是瀏覽器設置為啟用cookie)。Cookie的key/value可以由服務器端自己定義。

使用場景: 登錄狀態, 瀏覽歷史, 網站足跡

Cookie是存儲在瀏覽器中的一段純文本信息,建議不要存儲敏感信息如密碼,因為電腦上的瀏覽器可能被其它人使用

Cookie基於域名安全,不同域名的Cookie是不能互相訪問的

如訪問luffy.com時向瀏覽器中寫了Cookie信息,使用同一瀏覽器訪問baidu.com時,無法訪問到luffy.com寫的Cookie信息

瀏覽器的同源策略針對cookie也有限制作用.

當瀏覽器請求某網站時,會將本網站下所有Cookie信息提交給服務器,所以在request中可以讀取Cookie信息

設置cookie

設置cookie需要通過flask的Response響應對象來進行設置,由flask內部提供了一個make_response函數給我們可以快速創建響應對象

1 from flask imoprt Flask,make_response
2 @app.route('/set_cookie')
3 def set_cookie():
4     resp = make_response('this is to set cookie')
5     resp.set_cookie('username', 'xiaoming', max_age=3600)
6     # max_age 為cookie有效期,單位為秒
7     return resp

獲取cookie

1 from flask import Flask,request
2 @app.route('/get_cookie')
3 def resp_cookie():
4     resp = request.cookies.get('username')
5     return resp

五、session

對於敏感、重要的信息,建議要存儲在服務器端,不能存儲在瀏覽器中,如用戶名、余額、等級、驗證碼等信息

在服務器端進行狀態保持的方案就是Session

注意: Session依賴於Cookie,而且flask中使用session,需要配置SECRET_KEY選項,否則報錯.

設置session

1 from flask import session
2 @app.route('/set_session')
3 def set_session():
4     session['username'] = 'xiaoming'
5     return 'ok!'

獲取session

1 @app.route('/get_session')
2 def get_session():
3     return session.get('username')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM