Flask Web開發實戰(狼書)| 筆記第1、2章

前言

2023-8-11

以前對網站開發萌生了想法,又有些急于求成,在B站照著視頻敲了一個基于flask的博客系統。但對于程序的代碼難免有些囫圇吞棗,存在許多模糊或不太理解的地方,只會照葫蘆畫瓢。

而當自己想開發一個什么網站的時,就如同摸著石頭過河,常在許多小問題上卡住,不知怎么實現,也不知道需要去學習什么才能實現。例如,要做一個聊天室程序,我卻不知道在一方發出消息時,如何在另一方實時地顯示出來,思慮許久而終歸于放棄。

學習系統且詳細的知識有其好處,它可以沖退我那種徒手在黑暗中摸索的感覺。讀了“狼書”的兩個章節,自覺很有收獲,此前的許多疑惑也得到了解答。然凡事各有弊益,啃書不是易事,還需下苦功夫。

曾有人對我說,看視頻會更有效率。也許他是對的?但我好像更喜歡書籍給我的感覺。但有些諷刺的是,大學至今,我卻也沒看下來多少書,而時間在我休息的時候,它仍努力奔跑,兩載一晃而過。而不少人,也是這相似的困境吧?

回到本文,它是一篇讀書筆記,參雜少許個人想法但含量不高,所記零散,主要是作為個人提綱備忘,或許對諸位而言閱讀價值不高。若想學習 Flask 框架,我還是很推薦去讀“狼書”原著的。


文章目錄

    • 前言
    • 開始
      • Git使用
    • 1 初識Flask
      • 1.1 搭建開發環境
      • 1.2 簡單示例
    • 2 Flask與HTTP
      • 2.1 重定向回上一個頁面
      • 2.2 使用AJAX技術發送異步請求
      • 2.3 HTTP服務器推送
      • 2.4 Web安全防范

開始

5個難度遞增的案例:留言板SayHello,個人博客Bluelog,圖片社交網站Albumy,待辦事項程序Todoism,聊天室CatChat。

前端學習

在這里插入圖片描述

Web很多程序離不開javascript,它可以方便、簡潔地實現很多頁面按邏輯和功能。

了解Git:https://try.github.io/

文本編輯器

在這里插入圖片描述

作者的博客:http://greyli.com

Git使用

克隆本書代碼倉庫:

git clone https://github.com/greyli/helloflask.git

查看當前項目倉庫中包含的所有標簽:

git tag -n

簽出對應標簽版本的代碼:

git checkout foo

簽出前對文件做了修改,需要撤銷:

git reset --hard

使用diff命令比較兩個標簽對應版本之間的變化:

git diff foo bar

使用git客戶端直觀查看版本變化:

gitk

定期使用git fetch命令來更新本地倉庫:

git fetch --all
git fetch --tags
git reset --hard origin/master

在本地復制新的派生倉庫,后可以在本地自由修改其中的代碼:

git clone https://github.com/你的用戶名/helloflask.git

1 初識Flask

Web框架可以讓我們不用關心底層的請求響應處理,更方便地編寫Web程序。

兩個主要依賴:(p3)

  • WSGI(Web Server Gateway Interface,Web服務器網關接口)的工具集——Werkzeug(http://werkzeug.pocoo.org/)
  • Jinja2模板引擎

1.1 搭建開發環境

Pipenv:pip的加強版,讓包安裝、包依賴管理、虛擬環境管理更加方便。

創建虛擬環境:在項目根目錄(即helloflask文件夾中),使用pipenv install命令。Pipfile文件列出的依賴包也會一并被安裝。

在這里插入圖片描述

顯示激活虛擬環境:Pipenv會自動從項目目錄下的.env文件中加載環境變量。

# 激活
pipenv shell
# 退出
exit

臨時使用虛擬環境中的python解釋器:(更推薦)

pipenv run python hello.py

查看當前環境下的依賴情況

pipenv graph

關于Pipfile項目的更多情況,請訪問其主頁。

使用pipenv install命令安裝包時,都是安裝到虛擬環境中。相當于使用pip在激活虛擬環境的情況下安裝包。

在這里插入圖片描述

更新flask版本:(書中為flask-1.0.2)

pipenv update flask

集成開發環境:pycharm專業版提供了更多針對Flask開發的功能,比如創建Flask項目模板,Jinja2語法高亮,與Flask命令行功能集成等。

設置Python解釋器(好像已經不需要了):因為PyCharm未集成支持Pipenv。(p10)

1.2 簡單示例

from flask import Flask
app = Flask(__name__)@app.route('/')
def index():return '<h1>Hello Flask!</h1>'

Flask類表示一個Flask程序,實例化這個類就得到了我們的程序實例app。__name__對于文件app.py而言,值即為“app”,它幫助Flask在相應的文件夾里找到需要的資源,比如模板和靜態文件。(p12)

注冊路由:路由負責管理URL和函數之間的映射。

  • 一個視圖函數可以綁定多個路由。
  • 動態路由:可以傳遞參數,并可設置默認參數。

在這里插入圖片描述

:Flask內置一個開發服務器,但在實際生產環境中需要使用性能更好的生產服務器。

啟動開發服務器

# 未啟動虛擬環境下使用
pipenv run flask run
# 在虛擬環境中
flask run
# 命令未找到
python -m flask run

app.run()方法也可啟動開發服務器,已經不推薦使用。

flask尋找程序實例

  • 在當前目錄下,名為app.pywsgi.py的文件中尋找名為app的程序實例。
  • 根據環境變量FLASK_APP尋找。
# 在linux
$ export FLASK_APP=hello
# 在windows
> set FLASK_APP=hello

管理環境變量:使用python-dotenv包,從.env.flaskenv文件加載。其中.env文件存放一些敏感數據。

pipenv install python-dotenv

可在.flaskenv寫入:

# 默認為production(生產環境),開發模式將打開調試器和重載器。
FLASK_ENV=development

使用Pycharm的運行配置(而不使用命令行):在Run --> Edit Configurations(p19)

使服務器外部可見:讓局域網用戶可以通過你的內網IP進行訪問。想要公網訪問,可以考慮內網穿透工具、端口轉發工具等,如 ngrok、Localtunnel。

flask run --host=0.0.0.0

flask的環境變量:可通過FLASK_<COMMAND>_<OPTION>設置各種選項。

重載器:安裝 Watchdog。Werkzeug內置有stat重載器,但耗電嚴重且準確性一般。

# dev: 開發依賴的包
pipenv install watchdog --dev

打開PythonShell:使用flask打開的shell自動包含程序上下文,并且已經導入了app實例。

flask shell

Flask擴展:使用Flask提供的接口編寫的Python庫。擴展可以加速開發,但也會降低靈活性,并可能存在bug。

Flask項目配置:可能用到Flask提供的配置、擴展提供的、程序特定的配置。它們用Flask對象的app.config屬性作為統一的接口。

  • Flask配置章節:https://flask.pocoo.org/docs/latest/config/
app.config['ADMIN_NAME'] = 'Peter'
# 一次加載多個值
app.config.update()方法

URL:使用url_for(),方便url規則的修改。

  • 相對url與絕對url(p24)

自定義Flask命令

  • Click官方文檔(自定義命令):http://click.pocoo.org/6/
@app.cli.command()
def hello():click.echo('Hello, Human!')
> flask hello
Hello, Human!

視圖函數之名:可以溯源至MVC架構,即”模型 - 視圖 - 控制器”。但flask并不是MVC架構的框架,因為沒有內置數據模型的功能(需使用擴展),視圖函數成為控制器函數才更加合適。(p28)

2 Flask與HTTP

request對象常用的屬性和方法:(p43)

Response類常用屬性和方法:(p48)

查看路由列表:這個列表由app.url_map解析得到。其中static為Flask添加的特殊路由,用來訪問靜態文件。

> flask routes

Flask內置的URL變量轉換器:(p37)

URL規則中的轉換器<轉換器:變量名>

@app.route('goback/<int:year>')
def go_back(year):return '<p>Welcome to %d!</p>' % (2018 - year)

請求鉤子:也稱回調函數,可以用來注冊在請求處理的不同階段執行的處理函數,如預處理后處理,它們使用裝飾器 實現。(p58)

響應:大多數情況下,我們只負責返回響應的主體內容(而不負責首部及各種字段)。Flask會調用make_response()方法將視圖函數返回值轉換為響應對象。當然,響應也可以包含響應主體、狀態碼、首部字段 三個部分內容。

可使用redirect(<url字符串>)方法重定向。

@app.route('/')
def hello_flask():return '', 302, {'Location':'https://www.baidu.com'}

:狀態碼不可兒戲,如將上面的302改為202,則重定向會失效。

錯誤響應:在視圖函數中使用abort(<狀態碼>),例如:

@app.route('/404')
def not_found():abort(404)

響應格式:在 HTTP 響應中,數據可以通過多種格式傳輸,默認為 HTML。可以設置不同的 MIME 類型來標識不同的數據格式,MIME 類型在 Content-Type 字段中定義。

# method 1 - 修改響應對象的屬性
# @plain 純文本
from flask import make_response
...
response = make_response("hello")
response.mimetype = 'text/plain'
# method 2 - 設置首部字段
response.headers['Content-Type'] = 'text/html; charset=utf-8'
  • XMLapplication/xml,一般作為 AJAX 請求的響應格式,或是 Web API 的響應格式。

  • JSONapplication/json,指 JavaScript Object Notation(JavaScript對象表示法),更輕量、易解析。

    json模塊的dumps()方法,可以將python中的字典、列表、元組數據序列化為json字符串。

# 1 - python標準庫的json模塊
response = make_response(json.dumps(data))
response.mimetype = 'application/json'
return response
# 2 - 使用flask包裝的jsonify()函數
return jsonify(data)

Cookie:HTTP 是無狀態協議。Cookie是保存在瀏覽器上的小型文本數據,保存一定時間,在下一次向同一個服務器發送請求時附帶這些數據。但明文存儲存在安全隱患。

使用set_cookie()方法設置(參數見p68),從cookies屬性獲取。

Session:在Flask中,session對象用來存儲加密的cookie。

  • 設置程序密鑰:通過Flask.secret_key屬性;或環境變量SECRET_KEY(可保存在.env文件),在腳本中通過getenv()方法獲取。
import os
app.secret_key = os.getenv('SECRET_KEY', 'secret string')

疑問:寫進了環境變量還需再腳本中手動獲取?那我隨便用個環境變量名稱是不是也可以?

疑問:看不懂:使用session對象存儲的Cookie,用戶可以看到其加密后的值,但無法修改它。因為session中的內容使用密鑰進行簽名,一旦數據被修改,簽名的值也會變化。這樣再讀取時,就會驗證失敗,對應的session值也會失效。 (p51)

  • session cookie的保存時間

在這里插入圖片描述

上下文:Flask中有兩種上下文:程序上下文請求上下文

兩種上下文在視圖函數中都會自動激活,這也意味折一些依賴于上下文的函數只能在視圖函數中使用,如url_for()jsonify()等。

也可手動激活程序上下文:

>>> from app import app
>>> from flask import current_app# 方法1
>>> with app.app_context():... current_app.name# 方法2
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
>>> app_ctx.pop()# 激活請求上下文類似
>>> from app import app
>>> from flask import request
>>> with app.test_request_context('/hello'):...

在這里插入圖片描述

疑惑:g、request等對象如何區分不同的客戶端?

上下文鉤子:使用它注冊的回調函數會在程序上下文被銷毀時調用。

@app.teardown_appcontext
def teardown_db(exception):...db.close()

2.1 重定向回上一個頁面

利用referrerURL的查詢參數。(p59)

referrer:即訪問來源。當用戶在某個站點單擊鏈接,瀏覽器向新鏈接所在的服務器發起請求,請求的數據中包含的HTTP_REFERER字段記錄了用戶所在的原站點URL。

疑惑:書中判斷url是否安全的代碼(如下)使我困惑了許久:既然test_url中也與request.host_url做了拼接,那最后的netloc不是必然相同嗎?

后來我查找了urljoin(base, url)函數的處理機制:

  • 如果url是一個相對URL,那么urljoin會從url中獲取路徑部分,并于base中獲取的部分合并;
  • 如果url是一個絕對URL,則urljoin會直接返回url

那么在什么情況下,is_safe_url函數的返回值才為False呢?

  • 首先,target是一個絕對URL。
  • 同時,該絕對URL的協議或主機不是本機。

綜上,還是感覺該函數的邏輯寫得有些隱晦了,不便于理解(肯定不能是我太笨)。

def is_safe_url(target):ref_url = urlparse(request.host_url)test_url = urlparse(urljoin(request.host_url, target))return test_url.scheme in ('http', 'https') and \ref_url.netloc == test_url.netloc

2.2 使用AJAX技術發送異步請求

jQuery中和AJAX相關的方法和具體用法:http://api.jquery.com/category/ajax/

前言

在傳統的Web應用中,程序的操作都是基于請求響應循環來實現的。每當頁面狀態需要變動,或是需要更新數據時,都伴隨折一個發向服務器的請求。當服務器響應時,整個頁面會重載,并渲染新頁面

頻繁更新頁面會犧牲性能,且影響用戶體驗。

AJAX是指異步Javascript和XML(Asynchronous JavaScript And XML),是一系列技術的組合體,如XMLHttpRequest、JavaScript、DOM。它讓Web程序更像是程序,而非一堆用鏈接和按鈕鏈接起來的網頁資源

可以使用 jQuery 實現AJAX操作:函數ajax()可以發送AJAX請求。

在這里插入圖片描述

2.3 HTTP服務器推送

推送技術對比:https://stackoverflow.com/a/12855533/5511489

  • 傳統輪詢
  • 長輪詢
  • SSE(Server-Sent Events)
  • Websocket

2.4 Web安全防范

OWASP(Open Web Application Security Project,開放式Web程序安全項目):https://www.owasp.org 。(p66)

常見攻擊方式

  • 注入攻擊
  • XSS攻擊(Cross-Site Scripting,跨站腳本):將代碼注入被攻擊者的網站
  • CSRF攻擊:(Cross Site Request Forgery,跨站請求偽造):偽造用戶的登陸狀態。

提示:雖然在實際開發中,通過在”刪除“按鈕中加入鏈接來刪除資源非常方便,但安全問題應該作為編寫代碼時的第一考量,應該將這些按鈕內嵌在使用了POST方法的form元素中。攻擊者就無法通過GET請求來修改用戶的數據。

疑惑:未理解csrf攻擊的防御原理。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41687.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41687.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41687.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ubuntu部署haproxy

HAProxy是可提供高可用性、負載均衡以及基于TCP和HTTP應用的代理. 1、更新系統報 通過在終端中運行以下命令&#xff0c;確保所有系統包都是最新的 sudo apt updatesudo apt upgrade2、安裝Haproxy sudo apt install haproxy設置開機自動啟動haproxy服務 sudo systemctl en…

Lnton羚通關于如何解決nanoPC-T4 upgrade報錯問題?

nanoPC-T4 在 ??# sudo apt update 和 sudo apt upgrade??升級或安裝軟件 ??sudo apt install xxx??時遇到以下問題&#xff1a;??Failed to set up interface with /etc/hostapd/? Setting up hostapd (2:2.6-15ubuntu2.8) ... Job for hostapd.service failed be…

ssm+vue醫院住院管理系統源碼和論文PPT

ssmvue醫院住院管理系統源碼和論文PPT012 開發工具&#xff1a;idea 數據庫mysql5.7(mysql5.7最佳) 數據庫鏈接工具&#xff1a;navcat,小海豚等 開發技術&#xff1a;java ssm tomcat8.5 摘 要 隨著時代的發展&#xff0c;醫療設備愈來愈完善&#xff0c;醫院也變成人們生…

基于IMX6ULLmini的linux裸機開發系列一:匯編點亮LED

思來想去還是決定記錄一下點燈&#xff0c;畢竟萬物皆點燈嘛 編程步驟 使能GPIO時鐘 設置引腳復用為GPIO 設置引腳屬性(上下拉、速率、驅動能力) 控制GPIO引腳輸出高低電平 使能GPIO時鐘 其實和32差不多 先找到控制LED燈的引腳&#xff0c;也就是原理圖 文件名 C:/Us…

spring頭約束(全部)

文章目錄 spring-mvcspring-aopspring-txspring-contextspring-taskspring-cachespring-jdbcp命令空間spring-jeejmslangoxmutil總結 spring-mvc <beans xmlns"http://www.springframework.org/schema/beans" xmlns:xsi"http://www.w3.org/2001/XMLSchema-…

AUTOSAR NvM Block的三種類型

Native NVRAM block Native block是最基礎的NvM Block&#xff0c;可以用來存儲一個數據&#xff0c;可以配置長度、CRC等。 Redundant NVRAM block Redundant block就是在Native block的基礎上再加一個冗余塊&#xff0c;當Native block失效&#xff08;讀取失敗或CRC校驗失…

劍指offer44.數字序列中某一位的數字

最后一道題&#xff0c;我一定要自己做出來&#xff0c;想了不到一個小時想法差不多成熟了&#xff0c;但是有一個小細節出問題了&#xff0c;這個問題我在idea上debug都沒debug出來。我先講我的題解然后再講我這個小問題出在哪里吧。以下是我的代碼&#xff1a; class Soluti…

PHP手術麻醉系統源碼,自動生成麻醉和護理醫療文書

一套手術麻醉系統源碼&#xff0c;可二次開發 手術室麻醉臨床信息系統&#xff08;AIMS&#xff09;是應用于醫院手術室、麻醉科室的計算機軟件系統。該系統針對整個圍術期&#xff0c;對病人進行全程跟蹤與信息管理&#xff0c;自動集成病人HIS、LIS、RIS、PACS信息&#xff0…

【SA8295P 源碼分析】76 - Thermal 功耗 之 /dev/thermalmgr 相關調試命令匯總

【SA8295P 源碼分析】76 - Thermal 功耗 之 /dev/thermalmgr 相關調試命令匯總 1、配置文件:/mnt/etc/system/config/thermal-engine.conf2、獲取當前SOC所有溫度傳感器的溫度:cat /dev/thermalmgr3、查看所有 Thermal 默認配置和自定義配置:echo query config > /dev/th…

【Spring源碼】小白速通解析Spring源碼,從0到1,持續更新!

Spring源碼 參考資料 https://www.bilibili.com/video/BV1Tz4y1a7FM https://www.bilibili.com/video/BV1iz4y1b75q bean工廠 DefaultListableBeanFactory&#xff08;最原始&#xff09; bean的生命周期 創建&#xff08;實例化&#xff09;–>依賴注入–>-初始化…

利用vue-router跳轉的幾種方式

?1 <router-link> 2 this.$router.push 跳轉到指定路徑&#xff0c;并將跳轉頁面壓入history棧中&#xff0c;也就是添加了一個頁面記錄。3 this.$router.replace 跳轉到指定路徑&#xff0c;將history棧中的當前頁面替換為跳轉到的頁面。4 this.$router.go(n) 在his…

數據生成 | MATLAB實現WGAN生成對抗網絡數據生成

數據生成 | MATLAB實現WGAN生成對抗網絡數據生成 目錄 數據生成 | MATLAB實現WGAN生成對抗網絡數據生成生成效果基本描述程序設計參考資料 生成效果 基本描述 1.WGAN生成對抗網絡&#xff0c;數據生成&#xff0c;樣本生成程序&#xff0c;MATLAB程序&#xff1b; 2.適用于MATL…

從public static void main(String[] args)看如何構造數據

java語言中public static void main(String[] args)里面的ages有什么作用&#xff1f; 在Java語言中&#xff0c;public static void main(String[] args) 是一個特殊的方法&#xff0c;它是Java程序的入口點。當你運行一個Java程序時&#xff0c;程序會從這個方法開始執行。這…

【游戲評測】河洛群俠傳一周目玩后感

總游戲時長接近100小時&#xff0c;剛好一個月。 這兩天費了點勁做了些成就&#xff0c;刷了等級&#xff0c;把最終決戰做了。 總體感覺還是不錯的。游戲是開放世界3D游戲&#xff0c;Unity引擎&#xff0c;瑕疵很多&#xff0c;但勝在劇情扎實&#xff0c;天賦系統、秘籍功法…

kubernetes(二)

文章目錄 1. kubernetes常用資源1.1 deployment資源1.2 deployment升級和回滾1.3 tomcat連接mysql1.4 wordpress 2. kubernetes的附加組件2.1 kubernetes集群配置dns服務2.2 kubernetes的dns配置文件2.3 namespace命名空間2.4 kubernetes健康檢查2.4.1 健康檢查livenessprobo2.…

代碼隨想錄二刷day01

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、704. 二分查找二、35. 搜索插入位置三、34. 在排序數組中查找元素的第一個和最后一個位置四、69. x 的平方根五、367. 有效的完全平方數六、27. 移除元素七…

JDBC Vertica Source Connector 使用文檔

支持以下引擎 Spark Flink SeaTunnel Zeta 關鍵特性 批處理 精確一次性處理 列投影 并行處理 支持用戶自定義拆分 支持查詢 SQL 并實現投影效果 描述 通過 JDBC 讀取外部數據源數據。 支持的數據源信息 DatasourceSupported versionsDriverUrlMavenVerticaDifferent depen…

40、端口號和套接字

經過了上節的學習之后&#xff0c;接下來我們再要了解的一個知識就是端口號和套接字。尤其端口號&#xff0c;是傳輸層中最為重要的基礎概念之一&#xff0c;我們在以后的學習中會經常提及到端口號。 端口號 曾經在學習TCP/IP模型的時候&#xff0c;我們曾學過“SAP”即服務訪…

設計HTML5表格

在網頁設計中&#xff0c;表格主要用于顯示包含行、列結構的二維數據&#xff0c;如財務表格、調查數據、日歷表、時刻表、節目表等。在大多數情況下&#xff0c;這類信息都由列標題或行標題及數據構成。本章將詳細介紹表格在網頁設計中的應用&#xff0c;包括設計符合標準化的…

【第七講---視覺里程計1】

視覺里程計就是通過對圖像進行特征提取與匹配得到兩幀之間的位姿&#xff0c;并進行估計相機運動。 經典SLAM中以相機位姿-路標來描述SLAM過程 特征提取與匹配 路標是三維空間中固定不變的點&#xff0c;可以在特定位姿下觀測到在視覺SLAM中&#xff0c;可利用圖像特征點作為…