虛擬環境
之前我們的學習,所有的第三方包安裝都是直接通過pip install xx的方式進行安裝的,這樣安裝會將那個包安裝到你的系統級的Python環境中。但是這樣有一個問題,就是如果你現在用Django 1.10.x寫了個網站,然後你的領導跟你說,之前有一箇舊項目是用Django 0.9開發的,讓你來維護,但是Django 1.10不再兼容Django 0.9的一些語法了。這時候就會碰到一個問題,我如何在我的電腦中同時擁有Django 1.10和Django 0.9兩套環境呢?這時候我們就可以通過虛擬環境來解決這個問題。
cmd工具中使用pip install xxx是將xxx這個庫安裝在了全局環境中,而使用pycharm工具的時候,它自帶了一個虛擬環境,pip install 是將庫安裝在了pycharm的虛擬環境中,而且這兩個環境不共通。
pipenv
Windows安裝pipenv
pip install pipenv
Mac安裝
brew install pipenv
Linux安裝
pip install pipenv
pipfile和pipfile.lock
pip國內的一些鏡像
阿里雲: http://mirrors.aliyun.com/pypi/simple/
中國科技大學: https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) : http://pypi.douban.com/simple/
清華大學 : https://pypi.tuna.tsinghua.edu.cn/simple/
中國科學技術大學: http://pypi.mirrors.ustc.edu.cn/simple/
修改源方法:
pip install 庫名稱 -i 源地址
Pipfile文件
上面文件的各項代指
url # 指定國內pip源,不然下載庫會很慢
dev-packages # 開發環境
packages # 生產環境
django = "*" # *表示最新版本
requires # Python版本
pipfile.lock:詳細記錄環境依賴,並且利用了Hash算法保證了它完整對應關係
進入/退出/刪除虛擬環境
pipenv shell # 進入虛擬環境
exit # 退出虛擬環境
pipenv --rm # 刪除整個環境 不會刪除pipfile
下圖是配置虛擬環境安裝路徑的步驟(默認是在C:\Users\Administrator.virtualenvs)
上圖配置完成之後就可以在Pycharm中進行設置虛擬環境匹配設置:
完成之後代表:前面創建的虛擬環境已經與現在的Pycharm相互匹配。
2、管理開發環境
安裝在開發環境下
pipenv install --dev itchat
在虛擬環境中運行命令,使用run參數
pipenv run python manage.py runserver
pipenv有個缺點,lock不穩定而且時間非常長,所以安裝包的時候記得加上–skip-lock,最後開發完成要提價到倉庫的時候在pipenv lock
pipenv install django --skip-lock
3、Flask簡介
flask是一款非常流行的Python Web框架,出生於2010年,作者是Armin Ronacher,後來由於非常受歡迎,進而成爲一個正式的項目。
flask自2010年發佈第一個版本以來,大受歡迎,深得開發者的喜愛,並且在多個公司已經得到了應用,flask能如此流行的原因,可以分爲以下幾個特點:
- 微框架、簡潔、只做他需要做的,給開發者提供了很大的擴展性。
- Flask和相應的插件寫得很好。
- 開發效率非常高,比如使用SQLAlchemy的ORM操作數據庫可以節省開發者大量書寫sql的時間
Flask的靈活度非常之高,他不會幫你做太多的決策,一些你都可以按照自己的意願進行更改。
- 使用Flask開發數據庫的時候,具體是使用SQLAlchemy還是MongoEngine,選擇權完全掌握在你自己的手中。區別於Django,Django內置了非常完善和豐富的功能,並且如果你想替換成你自己想要的,要麼不支持,要麼非常麻煩。
- 把默認的Jinija2模板引擎替換成其他模板引擎都是非常容易的。
# 從flask框架中導入Flask類
from flask import Flask
# 傳入__name__初始化一個Flask實例
app = Flask(__name__)
# 裝飾器
# app.route裝飾器映射URL和執行的函數。這個設置將根URL映射到了hello_world函數上
@app.route("/") # http://127.0.0.1:5000/ 根目錄
def hello_world():
return "hello_world"
if __name__ == '__main__':
app.run()
# 運行本項目,host=0.0.0.0可以讓其他電腦也能訪問到該網站,port指定訪問的端口。默認的host是127.0.0.1,port爲5000
# app.run(host='0.0.0.0', port=9000)
然後點擊運行,在瀏覽器中輸入http://127.0.0.1:5000就能看到hello world了。需要說明一點的是,app.run這種方式只適合於開發,如果在生產環境中,應該使用Gunicorn或者uWSGI來啓動。如果是在終端運行的,可以按ctrl+c來讓服務停止。
設置Flask爲DEBUG模式
默認情況下flask不會開啓DEBUG模式,開啓DEBUG模式後,flask會在每次保存代碼的時候自動的重新載入代碼,並且如果代碼有錯誤,會在終端進行提示。
開啓DEBUG模式有三種方式
- 直接在應用對象上設置
app.debug = True
app.run()
- 在執行run方法的時候,傳遞參數進去
app.run(debug=True)
上圖中的Debug mode: on/Debugger is active!等都說明了Debug模式都已經開啓了。
上圖中的Debugger PIN是用於在瀏覽器網頁端進行修改錯誤時候用於驗證的。
- 在config屬性中設置
# config 配置文件
app.config.update()
print(type(app.config)) # <class 'flask.config.Config'>
print(isinstance(app.config, dict)) # True 說明config類型是dict類型,數據類型中可以使用update方法的就是dict類型
app.config.update(DEBUG=True)
app.run()
需要注意的是,只能在開發環境下開啓DEBUG模式,因爲DEBUG模式會帶來非常大的安全隱患。
在開啓了DEBUG模式後,當程序有異常而進入錯誤堆棧模式,你第一次點擊某個堆棧想查看變量值的時候,頁面會彈出一個對話框,讓你輸入PIN值,這個PIN值在你啓動的時候就會出現,比如在剛剛啓動的項目中的PIN值爲145-623-872,你輸入這個值後,Werkzeug會把這個PIN值作爲cookie的一部分保存起來,並在8小時候過期,8小時以內不需要再輸入PIN值。這樣做的目的是爲了更加的安全,讓調試模式下的攻擊者更難攻擊到本站。
4、配置文件
Flask項目的配置,都是通過app.config對象來進行配置的。比如要配置一個項目處於DEBUG模式下,那麼可以使用app.config['DEBUG] = True來進行設置,那麼Flask項目將以DEBUG模式運行。在Flask項目中,有四種方式進行項目的配置
- 直接硬編碼
app = Flask(__name__)
app.config['DEBUG'] = True
- 因爲app.config是flask.config.Config的實例,而Config類是繼承自dict,因此可以通過update方法
app.config.update(
DEBUG=True,
SECRET_KEY='...'
)
- 如果你的配置項特別多,你可以把所有的配置項都放在一個模塊中,然後通過加載模塊的方式進行配置,假設有一個settings.py模塊,專門用來存儲配置項的,此時你可以通過app.config.from_object()方法進行加載,並且該方法既可以接收模塊的的字符串名稱,也可以模塊對象
# 1. 通過模塊字符串
app.config.from_object('settings')
# 2. 通過模塊對象
import settings
app.config.from_object(settings)
4. 也可以通過另外一個方法加載,該方法就是app.config.from_pyfile(),該方法傳入一個文件名,通常是以.py結尾的文件,但也不限於只使用.py後綴的文件
app.config.from_pyfile('settings.py',silent=True)
5、URL與視圖
URL與視圖
URL與函數的映射
從之前的helloworld.py文件中,我們已經看到,一個URL要與執行函數進行映射,使用的是@app.route裝飾器。@app.route裝飾器中,可以指定URL的規則來進行更加詳細的映射,比如現在要映射一個文章詳情的URL,文章詳情的URL是/article/id/,id有可能爲1、2、3…,那麼可以通過以下方式。
# 從flask框架中導入Flask類
from flask import Flask
# 導入flask中的config
# from flask import config
# 導入config.py的文件
import config
# 傳入__name__初始化一個Flask實例
app = Flask(__name__)
# 裝飾器
# app.route裝飾器映射URL和執行的函數。這個設置將根URL映射到了hello_world函數上
@app.route("/") # http://127.0.0.1:5000/ 根目錄
def hello_world():
return "hello_world"
@app.route("/xxx")
def hello_xxx():
return "hello_xxx"
@app.route("/123")
def hello_123():
return "hello_world:123"
if __name__ == '__main__':
app.config.from_pyfile('config.py')
app.run()
@app.route("/list/<id>")
def article_list(id):
return "這是第{}篇文章".format(id)
其中,尖括號是固定寫法,語法爲,variable默認的數據類型是字符串。如果需要指定類型,則要寫成converter:variable,其中converter就是類型名稱,可以有以下幾種:
string: 默認的數據類型,接受沒有任何斜槓/的字符串。
int: 整形
float: 浮點型。
path: 和string類似,但是可以傳遞斜槓/。
uuid: uuid類型的字符串。(永遠不會重複的字符串)
any:可以指定多種路徑
@app.route("/list/<int:id>") # int:限制數據類型
def article_list(id):
return "這是第{}篇文章".format(id)
@app.route("/list/<path:id>") # int:限制數據類型
def article_detail(id):
return "detail:這是第{}篇文章".format(id)
# article,blog 不同參數的形式
@app.route('/<any(article,blog):url_path>/') # 注意最後的 / 符號
def item(url_path):
return url_path
如果不想定製子路徑來傳遞參數,也可以通過傳統的?=的形式來傳遞參數,例如:/article?id=xxx,這種情況下,可以通過request.args.get(‘id’)來獲取id的值。如果是post方法,則可以通過request.form.get(‘id’)來進行獲取。
from flask import request
@app.route("/wd")
def zzzz():
return request.args.get("name")