知了課堂Python Flask零基礎到項目實戰系列視頻的所有筆記,現整理在下,視頻地址:
筆記目錄:
起步
安裝Python2.7:
- Mac下使用Python2.7.
- Windows下安裝Python2.7.
- 從python官網下載python2.7的版本。
- 雙擊python2.7,然后選擇安裝路徑,一頓下一步就可以了。
- 設置環境變量,把python的安裝路徑添加到PATH變量中。
- 還需要設置一個環境變量,一定要設置,不然后面就不能正常安裝flask了。
Python虛擬環境介紹與安裝:
- 因為python的框架更新迭代太快了,有時候需要在電腦上存在一個框架的多個版本,這時候虛擬環境就可以解決這個問題。
- 通過以下命令安裝虛擬環境:pip install virtualenv
- 開辟新的虛擬環境:virtualenv [virtualenv-name]
- 激活虛擬環境:
- [類linux]:source [虛擬環境的目錄]/bin/activate
- [windows]:直接進入到虛擬環境的目錄,然后執行activate
- 退出虛擬環境:deactivate
pip安裝flask:
- 執行activate腳本,進入指定的虛擬環境。
- 在該虛擬環境中,執行以下命令安裝:pip install flask
- 驗證flask是否安裝成功:
- 進入python命令行。
>>> import flask >>> print flask.__version__
認識url:
- 如果使用的是http協議,那么瀏覽器就會使用80端口去請求這個服務器的資源。
- 如果使用的是https協議,那么瀏覽器會使用443端口去請求這個服務器的資源。
http://www.jianshu.com/
https://www.baidu.com/
https://www.baidu.com/s?ie=utf-8&f=8
URL詳解
URL是Uniform Resource Locator的簡寫,統一資源定位符。
一個URL由以下幾部分組成:
scheme://host:port/path/?query-string=xxx#anchor
scheme:代表的是訪問的協議,一般為http或者https以及ftp等。
host:主機名,域名,比如www.baidu.com。
port:端口號。當你訪問一個網站的時候,瀏覽器默認使用80端口。
path:查找路徑。比如:www.jianshu.com/trending/now,后面的trending/now就是path。
query-string:查詢字符串,比如:www.baidu.com/s?wd=python,后面的wd=python就是查詢字符串。
anchor:錨點,后台一般不用管,前端用來做頁面定位的。
web服務器和應用服務器以及web應用框架:
web服務器:負責處理http請求,響應靜態文件,常見的有Apache,Nginx以及微軟的IIS.
應用服務器:負責處理邏輯的服務器。比如php、python的代碼,是不能直接通過nginx這種web服務器來處理的,只能通過應用服務器來處理,常見的應用服務器有uwsgi、tomcat等。
web應用框架:一般使用某種語言,封裝了常用的web功能的框架就是web應用框架,flask、Django以及Java中的SSH(Structs2+Spring3+Hibernate3)框架都是web應用框架。
Flask
第一個flask程序講解:
-
第一次創建項目的時候,要添加flask的虛擬環境。添加虛擬環境的時候,一定要選擇到python這個執行文件。
比如你的flask的虛擬環境的目錄在/User/Virtualenv/flask-env/bin/python。 -
flask程序代碼的詳細解釋:
# 從flask這個框架中導入Flask這個類 from flask import Flask # 初始化一個Flask對象 # Flaks() # 需要傳遞一個參數__name__ # 1. 方便flask框架去尋找資源 # 2. 方便flask插件比如Flask-Sqlalchemy出現錯誤的時候,好去尋找問題所在的位置 app = Flask(__name__)
@app.route是一個裝飾器
@開頭,並且在函數的上面,說明是裝飾器
這個裝飾器的作用,是做一個url與視圖函數的映射
127.0.0.1:5000/ -> 去請求hello_world這個函數,然后將結果返回給瀏覽器
@app.route('/')
def hello_world():
return '我是第一個flask程序'如果當前這個文件是作為入口程序運行,那么就執行app.run()
if name == 'main':
# app.run()
# 啟動一個應用服務器,來接受用戶的請求
# while True:
# listen()
app.run()
設置debug模式:
- 在app.run()中傳入一個關鍵字參數debug,app.run(debug=True),就設置當前項目為debug模式。
- debug模式的兩大功能:
- 當程序出現問題的時候,可以在頁面中看到錯誤信息和出錯的位置。
- 只要修改了項目中的
python
文件,程序會自動加載,不需要手動重新啟動服務器。
使用配置文件:
- 新建一個
config.py
文件 - 在主app文件中導入這個文件,並且配置到
app
中,示例代碼如下:import config app.config.from_object(config)
- 還有許多的其他參數,都是放在這個配置文件中,比如
SECRET_KEY
和SQLALCHEMY
這些配置,都是在這個文件中。
url傳參數:
- 參數的作用:可以在相同的URL,但是指定不同的參數,來加載不同的數據。
- 在flask中如何使用參數:
@app.route('/article/<id>') def article(id): return u'您請求的參數是:%s' % id
- 參數需要放在兩個尖括號中。
- 視圖函數中需要放和url中的參數同名的參數。
反轉URL:
- 什么叫做反轉URL:從視圖函數到url的轉換叫做反轉url
- 反轉url的用處:
- 在頁面重定向的時候,會使用url反轉。
- 在模板中,也會使用url反轉。
頁面跳轉和重定向:
- 用處:在用戶訪問一些需要登錄的頁面的時候,如果用戶沒有登錄,那么可以讓她重定向到登錄頁面。
- 代碼實現:
from flask import redirect,url redirect(url_for('login'))
url鏈接:使用url_for(視圖函數名稱)
可以反轉成url。
加載靜態文件:
- 語法:
url_for('static',filename='路徑')
- 靜態文件,flask會從
static
文件夾中開始尋找,所以不需要再寫static
這個路徑了。 - 可以加載
css
文件,可以加載js
文件,還有image
文件。第一個:加載css文件 <link rel="stylesheet" href="{{ url_for('static',filename='css/index.css') }}"> 第二個:加載js文件 <script src="{{ url_for('static',filename='js/index.js') }}"></script> 第三個:加載圖片文件 <img src="{{ url_for('static',filename='images/zhiliao.png') }}" alt="">
get請求和post請求:
- get請求:
- 使用場景:如果只對服務器獲取數據,並沒有對服務器產生任何影響,那么這時候使用get請求。
- 傳參:get請求傳參是放在url中,並且是通過
?
的形式來指定key和value的。
- post請求:
- 使用場景:如果要對服務器產生影響,那么使用post請求。
- 傳參:post請求傳參不是放在url中,是通過
form data
的形式發送給服務器的。
get和post請求獲取參數:
- get請求是通過
flask.request.args
來獲取。 - post請求是通過
flask.request.form
來獲取。 - post請求在模板中要注意幾點:
- input標簽中,要寫name來標識這個value的key,方便后台獲取。
- 在寫form表單的時候,要指定
method='post'
,並且要指定action='/login/'
。
- 示例代碼:
<form action="{{ url_for('login') }}" method="post"> <table> <tbody> <tr> <td>用戶名:</td> <td><input type="text" placeholder="請輸入用戶名" name="username"></td> </tr> <tr> <td>密碼:</td> <td><input type="text" placeholder="請輸入密碼" name="password"></td> </tr> <tr> <td></td> <td><input type="submit" value="登錄"></td> </tr> </tbody> </table> </form>
保存全局變量的g屬性:
g:global
- g對象是專門用來保存用戶的數據的。
- g對象在一次請求中的所有的代碼的地方,都是可以使用的。
鈎子函數(hook):
- before_request:
- 在請求之前執行的
- 是在視圖函數執行之前執行的
- 這個函數只是一個裝飾器,他可以把需要設置為鈎子函數的代碼放到視圖函數執行之前來執行
- context_processor:
- 上下文處理器應該返回一個字典。字典中的
key
會被模板中當成變量來渲染。 - 上下文處理器中返回的字典,在所有頁面中都是可用的。
- 被這個裝飾器修飾的鈎子函數,必須要返回一個字典,即使為空也要返回。
- 上下文處理器應該返回一個字典。字典中的
cookie:
cookie
出現的原因:在網站中,http請求是無狀態的。也就是說即使第一次和服務器連接后並且登錄成功后,第二次請求服務器依然不能知道當前請求是哪個用戶。cookie的出現就是為了解決這個問題,第一次登錄后服務器返回一些數據(cookie)給瀏覽器,然后瀏覽器保存在本地,當該用戶發送第二次請求的時候,就會自動的把上次請求存儲的cookie數據自動的攜帶給服務器,服務器通過瀏覽器攜帶的數據就能判斷當前用戶是哪個了。- 如果服務器返回了
cookie
給瀏覽器,那么瀏覽器下次再請求相同的服務器的時候,就會自動的把cookie
發送給瀏覽器,這個過程,用戶根本不需要管。 cookie
是保存在瀏覽器中的,相對的是瀏覽器。
session:
session
介紹:session和cookie的作用有點類似,都是為了存儲用戶相關的信息。不同的是,cookie是存儲在本地瀏覽器,而session存儲在服務器。存儲在服務器的數據會更加的安全,不容易被竊取。但存儲在服務器也有一定的弊端,就是會占用服務器的資源,但現在服務器已經發展至今,一些session信息還是綽綽有余的。- 使用
session
的好處:- 敏感數據不是直接發送回給瀏覽器,而是發送回一個
session_id
,服務器將session_id
和敏感數據做一個映射存儲在session
(在服務器上面)中,更加安全。 session
可以設置過期時間,也從另外一方面,保證了用戶的賬號安全。
- 敏感數據不是直接發送回給瀏覽器,而是發送回一個
flask中的session工作機制:
- flask中的session機制是:把敏感數據經過加密后放入
session
中,然后再把session
存放到cookie
中,下次請求的時候,再從瀏覽器發送過來的cookie
中讀取session
,然后再從session
中讀取敏感數據,並進行解密,獲取最終的用戶數據。 - flask的這種
session
機制,可以節省服務器的開銷,因為把所有的信息都存儲到了客戶端(瀏覽器)。 - 安全是相對的,把
session
放到cookie
中,經過加密,也是比較安全的,這點大家放心使用就可以了。
操作session:
- session的操作方式:
- 使用
session
需要從flask
中導入session
,以后所有和sessoin
相關的操作都是通過這個變量來的。 - 使用
session
需要設置SECRET_KEY
,用來作為加密用的。並且這個SECRET_KEY
如果每次服務器啟動后都變化的話,那么之前的session
就不能再通過當前這個SECRET_KEY
進行解密了。 - 操作
session
的時候,跟操作字典是一樣的。 - 添加
session
:session['username']
。 - 刪除:
session.pop('username')
或者del session['username']
。 - 清除所有
session
:session.clear()
- 獲取
session
:session.get('username')
- 使用
- 設置session的過期時間:
- 如果沒有指定session的過期時間,那么默認是瀏覽器關閉后就自動結束
- 如果設置了session的permanent屬性為True,那么過期時間是31天。
- 可以通過給
app.config
設置PERMANENT_SESSION_LIFETIME
來更改過期時間,這個值的數據類型是datetime.timedelay
類型。
Jinja2
Flask渲染Jinja2模板和傳參:
- 如何渲染模板:
- 模板放在
templates
文件夾下 - 從
flask
中導入render_template
函數。 - 在視圖函數中,使用
render_template
函數,渲染模板。注意:只需要填寫模板的名字,不需要填寫templates
這個文件夾的路徑。
- 模板放在
- 模板傳參:
- 如果只有一個或者少量參數,直接在
render_template
函數中添加關鍵字參數就可以了。 - 如果有多個參數的時候,那么可以先把所有的參數放在字典中,然后在
render_template
中,
使用兩個星號,把字典轉換成關鍵參數傳遞進去,這樣的代碼更方便管理和使用。
- 如果只有一個或者少量參數,直接在
- 在模板中,如果要使用一個變量,語法是:
{{params}}
- 訪問模型中的屬性或者是字典,可以通過
{{params.property}}
的形式,或者是使用{{params['age']}}
.
過濾器:
-
介紹和語法:
- 介紹:過濾器可以處理變量,把原始的變量經過處理后再展示出來。作用的對象是變量。
- 語法:
{{ avatar|default('xxx') }}
-
default過濾器:如果當前變量不存在,這時候可以指定默認值。
-
length過濾器:求列表或者字符串或者字典或者元組的長度。
-
常用的過濾器:
abs(value):返回一個數值的絕對值。示例:-1|abs
default(value,default_value,boolean=false):如果當前變量沒有值,則會使用參數中的值來代替。示例:name|default('xiaotuo')——如果name不存在,則會使用xiaotuo來替代。boolean=False默認是在只有這個變量為undefined的時候才會使用default中的值,如果想使用python的形式判斷是否為false,則可以傳遞boolean=true。也可以使用or來替換。
escape(value)或e:轉義字符,會將<、>等符號轉義成HTML中的符號。示例:content|escape或content|e。
first(value):返回一個序列的第一個元素。示例:names|first
format(value,*arags,**kwargs):格式化字符串。比如:{{ "%s" - "%s"|format('Hello?',"Foo!") }}
將輸出:Helloo? - Foo!
last(value):返回一個序列的最后一個元素。示例:names|last。length(value):返回一個序列或者字典的長度。示例:names|length。
join(value,d=u''):將一個序列用d這個參數的值拼接成字符串。
safe(value):如果開啟了全局轉義,那么safe過濾器會將變量關掉轉義。示例:content_html|safe。
int(value):將值轉換為int類型。
float(value):將值轉換為float類型。
lower(value):將字符串轉換為小寫。
upper(value):將字符串轉換為小寫。
replace(value,old,new): 替換將old替換為new的字符串。
truncate(value,length=255,killwords=False):截取length長度的字符串。
striptags(value):刪除字符串中所有的HTML標簽,如果出現多個空格,將替換成一個空格。
trim:截取字符串前面和后面的空白字符。
string(value):將變量轉換成字符串。
wordcount(s):計算一個長字符串中單詞的個數。
if判斷:
- 語法:
{% if xxx %} {% else %} {% endif %}
- if的使用,可以和python中相差無幾。
for循環遍歷列表和字典:
- 字典的遍歷,語法和
python
一樣,可以使用items()
、keys()
、values()
、iteritems()
、iterkeys()
、itervalues()
{% for k,v in user.items() %} <p>{{ k }}:{{ v }}</p> {% endfor %}
- 列表的遍歷:語法和
python
一樣。{% for website in websites %} <p>{{ website }}</p> {% endfor %}
繼承和block:
- 繼承作用和語法:
- 作用:可以把一些公共的代碼放在父模板中,避免每個模板寫同樣的代碼。
- 語法:
{% extends 'base.html' %}
- block實現:
- 作用:可以讓子模板實現一些自己的需求。父模板需要提前定義好。
- 注意點:字模板中的代碼,必須放在block塊中。
數據庫
Mac和Windows下數據庫的安裝:
- Mysql為例
- https://dev.mysql.com/downloads/mysql/
- Mac上安裝Mysql很簡單,直接一頓下一步安裝就可以了。
- 設置初始化密碼的命令是:
mysqladmin -uroot password [password]
- windows:
*. 如果沒有安裝.net Framework 4,就在那個提示框中,找到下載的url,下載下來,安裝即可。
*. 如果沒有安裝Microsoft Visual C++ x64,那么就需要谷歌或者百度下載這個軟件進行安裝即可。
MySQL-python中間件的介紹與安裝:
- 如果是在類unix系統上,直接進入虛擬環境,輸入
sudo pip install mysql-python
。 - 如果是在windows系統上,那么在這里下載
http://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python
下載MySQL_python‑1.2.5‑cp27‑none‑win_amd64.whl
,然后在命令行中,進入到MySQL_python‑1.2.5‑cp27‑none‑win_amd64.whl
所在的目錄,輸入以下命令進行安裝:pip install MySQL_python‑1.2.5‑cp27‑none‑win_amd64.whl
Flask-SQLAlchemy的介紹與安裝:
- ORM:Object Relationship Mapping(模型關系映射)。
- flask-sqlalchemy是一套ORM框架。
- ORM的好處:可以讓我們操作數據庫跟操作對象是一樣的,非常方便。因為一個表就抽象成一個類,一條數據就抽象成該類的一個對象。
- 安裝
flask-sqlalchemy
:sudo pip install flask-sqlalchemy
。
Flask-SQLAlchemy的使用:
-
初始化和設置數據庫配置信息:
- 使用flask_sqlalchemy中的SQLAlchemy進行初始化:
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) db = SQLAlchemy(app)
- 使用flask_sqlalchemy中的SQLAlchemy進行初始化:
-
設置配置信息:在
config.py
文件中添加以下配置信息:# dialect+driver://username:password@host:port/database DIALECT = 'mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = 'root' HOST = '127.0.0.1' PORT = '3306' DATABASE = 'db_demo1' SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST ,PORT,DATABASE) SQLALCHEMY_TRACK_MODIFICATIONS = False
-
在主
app
文件中,添加配置文件:app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app)
-
做測試,看有沒有問題:
db.create_all()
如果沒有報錯,說明配置沒有問題,如果有錯誤,可以根據錯誤進行修改。
使用Flask-SQLAlchemy創建模型與表的映射:
- 模型需要繼承自
db.Model
,然后需要映射到表中的屬性,必須寫成db.Column
的數據類型。 - 數據類型:
db.Integer
代表的是整形.db.String
代表的是varchar
,需要指定最長的長度。db.Text
代表的是text
。
- 其他參數:
primary_key
:代表的是將這個字段設置為主鍵。autoincrement
:代表的是這個主鍵為自增長的。nullable
:代表的是這個字段是否可以為空,默認可以為空,可以將這個值設置為False
,在數據庫中,這個值就不能為空了。
- 最后需要調用
db.create_all
來將模型真正的創建到數據庫中。
Flask-SQLAlchemy數據的增、刪、改、查:
- 增:
# 增加: article1 = Article(title='aaa',content='bbb') db.session.add(article1) # 事務 db.session.commit()
- 查:
# 查 # select * from article where article.title='aaa'; article1 = Article.query.filter(Article.title == 'aaa').first() print 'title:%s' % article1.title print 'content:%s' % article1.content
- 改:
# 改: # 1. 先把你要更改的數據查找出來 article1 = Article.query.filter(Article.title == 'aaa').first() # 2. 把這條數據,你需要修改的地方進行修改 article1.title = 'new title' # 3. 做事務的提交 db.session.commit()
- 刪:
# 刪 # 1. 把需要刪除的數據查找出來 article1 = Article.query.filter(Article.content == 'bbb').first() # 2. 把這條數據刪除掉 db.session.delete(article1) # 3. 做事務提交 db.session.commit()
Flask-SQLAlchemy外鍵及其關系:
-
外鍵:
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(100),nullable=False) class Article(db.Model): __tablename__ = 'article' id = db.Column(db.Integer, primary_key=True, autoincrement=True) title = db.Column(db.String(100),nullable=False) content = db.Column(db.Text,nullable=False) author_id = db.Column(db.Integer,db.ForeignKey('user.id')) author = db.relationship('User',backref=db.backref('articles'))
-
author = db.relationship('User',backref=db.backref('articles'))
解釋:- 給
Article
這個模型添加一個author
屬性,可以訪問這篇文章的作者的數據,像訪問普通模型一樣。 backref
是定義反向引用,可以通過User.articles
訪問這個模型所寫的所有文章。
- 給
-
多對多:
- 多對多的關系,要通過一個中間表進行關聯。
- 中間表,不能通過
class
的方式實現,只能通過db.Table
的方式實現。 - 設置關聯:
tags = db.relationship('Tag',secondary=article_tag,backref=db.backref('articles'))
需要使用一個關鍵字參數secondary=中間表
來進行關聯。 - 訪問和數據添加可以通過以下方式進行操作:
- 添加數據:
article1 = Article(title='aaa') article2 = Article(title='bbb') tag1 = Tag(name='111') tag2 = Tag(name='222') article1.tags.append(tag1) article1.tags.append(tag2) article2.tags.append(tag1) article2.tags.append(tag2) db.session.add(article1) db.session.add(article2) db.session.add(tag1) db.session.add(tag2) db.session.commit()
- 訪問數據:
article1 = Article.query.filter(Article.title == 'aaa').first() tags = article1.tags for tag in tags: print tag.name
- 添加數據:
Flask-Script的介紹與安裝:
-
Flask-Script:Flask-Script的作用是可以通過命令行的形式來操作Flask。例如通過命令跑一個開發版本的服務器、設置數據庫,定時任務等。
-
安裝:首先進入到虛擬環境中,然后
pip install flask-script
來進行安裝。 -
如果直接在主
manage.py
中寫命令,那么在終端就只需要python manage.py command_name
就可以了。 -
如果把一些命令集中在一個文件中,那么在終端就需要輸入一個父命令,比如
python manage.py db init
。 -
例子:
from flask_script import Manager from flask_script_demo import app from db_scripts import DBManager manager = Manager(app)
和數據庫相關的操作,我都放在一起
@manager.command
def runserver():
print '服務器跑起來了!!!!!'
manager.add_command('db',DBManager)if name == 'main':
manager.run() -
有子命令的例子:
#encoding: utf-8 from flask_script import Manager DBManager = Manager() @DBManager.command def init(): print '數據庫初始化完成' @DBManager.command def migrate(): print '數據表遷移成功'
分開models
以及解決循環引用:
- 分開models的目的:為了讓代碼更加方便的管理。
- 如何解決循環引用:把
db
放在一個單獨的文件中,切斷循環引用的線條就可以了。
Flask-Migrate的介紹與安裝:
- 介紹:因為采用
db.create_all
在后期修改字段的時候,不會自動的映射到數據庫中,必須刪除表,然后重新運行db.craete_all
才會重新映射,這樣不符合我們的需求。因此flask-migrate就是為了解決這個問題,她可以在每次修改模型后,可以將修改的東西映射到數據庫中。 - 首先進入到你的虛擬環境中,然后使用
pip install flask-migrate
進行安裝就可以了。 - 使用
flask_migrate
必須借助flask_scripts
,這個包的MigrateCommand
中包含了所有和數據庫相關的命令。 flask_migrate
相關的命令:python manage.py db init
:初始化一個遷移腳本的環境,只需要執行一次。python manage.py db migrate
:將模型生成遷移文件,只要模型更改了,就需要執行一遍這個命令。python manage.py db upgrade
:將遷移文件真正的映射到數據庫中。每次運行了migrate
命令后,就記得要運行這個命令。
- 注意點:需要將你想要映射到數據庫中的模型,都要導入到
manage.py
文件中,如果沒有導入進去,就不會映射到數據庫中。 manage.py
的相關代碼:from flask_script import Manager from migrate_demo import app from flask_migrate import Migrate,MigrateCommand from exts import db from models import Article # init # migrate # upgrade # 模型 -> 遷移文件 -> 表 manager = Manager(app) # 1. 要使用flask_migrate,必須綁定app和db migrate = Migrate(app,db) # 2. 把MigrateCommand命令添加到manager中 manager.add_command('db',MigrateCommand) if __name__ == '__main__': manager.run()