Django3.x 初體驗(yàn)

2019年12月2日院促,Django終于正式發(fā)布了3.0版本。懷著無比的期待夭织,我們來嘗試一下吧吃环!

Django3.0的新特性,其中最主要的就是加入對ASGI的支持伊滋,實(shí)現(xiàn)全雙工的異步通信碳却。

##?Python?Web框架?Django?高級實(shí)戰(zhàn)編程

視頻分享地址:?[https://study.163.com/course/introduction/1209407824.htm?share=2&shareId=400000000535031](https://study.163.com/course/introduction/1209407824.htm?share=2&shareId=400000000535031)

使用上面的鏈接地址進(jìn)入,聯(lián)系QQ??1064468942?可獲得?部分?學(xué)費(fèi)退還?喔,?實(shí)際支出?將少于?所標(biāo)識的價(jià)格

Django高級實(shí)戰(zhàn)課程源代碼與資源包

源代碼分為兩部分笑旺,兩個網(wǎng)站的源代碼都是按照開發(fā)進(jìn)度按章保存的:

新聞博客問答聊天網(wǎng)站的源代碼:?

鏈接:https://pan.baidu.com/s/1cd7HU46ovf_N6foIYpueFA?

最終部署版本?鏈接:https://pan.baidu.com/s/1lFjwT-ygYynHvEgUufWUEQ?

樂乎在線閱讀網(wǎng)的源代碼:?

鏈接:https://pan.baidu.com/s/10WbOVte0PMiIStQEQC4nVQ

網(wǎng)盤提取碼請查看相關(guān)視頻

##?創(chuàng)建Django3工程

利用Pycharm的方便昼浦,直接通過virtualenv創(chuàng)建虛擬環(huán)境,并安裝Django3.0筒主。

打開控制臺关噪,看看都安裝了哪些庫:

```bash

(venv)?D:\work\for_test\django3>pip?list

Package????Version

------

asgiref????3.2.3

Django?????3.0

pip????????10.0.1

pytz???????2019.3

setuptools?39.1.0

sqlparse???0.3.0

```

除了pytz和sqlparse,又自動安裝了asgiref乌妙。

asigref由Django軟件基金會開發(fā)和維護(hù)使兔,是一個Django生態(tài)中的庫。

先啟動一下服務(wù)器藤韵,看看Django是否正常運(yùn)行:

![在這里插入圖片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly93d3cubGl1amlhbmdibG9nLmNvbS9zdGF0aWMvaW1hZ2VzL2Jsb2cvMTU3NTQyNDg2ODgxOS5wbmc?x-oss-process=image/format,png)可以看到虐沥,運(yùn)行沒問題!

##?學(xué)習(xí)官方文檔

畢竟是新特性泽艘,先到官網(wǎng)看看文檔怎么寫的欲险。

如下所示:

![在這里插入圖片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly93d3cubGl1amlhbmdibG9nLmNvbS9zdGF0aWMvaW1hZ2VzL2Jsb2cvMTU3NTQyNTAzMDAyMC5wbmc?x-oss-process=image/format,png)主要內(nèi)容是關(guān)于ASGI服務(wù)如何部署的,如下所示:

```

How?to?deploy?with?ASGI

As?well?as?WSGI,?Django?also?supports?deploying?on?ASGI,?the?emerging?Python?standard?for?asynchronous?web?servers?and?applications.

Django’s?startproject?management?command?sets?up?a?default?ASGI?configuration?for?you,?which?you?can?tweak?as?needed?for?your?project,?and?direct?any?ASGI-compliant?application?server?to?use.

Django?includes?getting-started?documentation?for?the?following?ASGI?servers:

How?to?use?Django?with?Daphne

How?to?use?Django?with?Uvicorn

The?application?object

Like?WSGI,?ASGI?has?you?supply?an?application?callable?which?the?application?server?uses?to?communicate?with?your?code.?It’s?commonly?provided?as?an?object?named?application?in?a?Python?module?accessible?to?the?server.

The?startproject?command?creates?a?file?<project_name>/asgi.py?that?contains?such?an?application?callable.

It’s?not?used?by?the?development?server?(runserver),?but?can?be?used?by?any?ASGI?server?either?in?development?or?in?production.

ASGI?servers?usually?take?the?path?to?the?application?callable?as?a?string;?for?most?Django?projects,?this?will?look?like?myproject.asgi:application.

Warning

While?Django’s?default?ASGI?handler?will?run?all?your?code?in?a?synchronous?thread,?if?you?choose?to?run?your?own?async?handler?you?must?be?aware?of?async-safety.

Do?not?call?blocking?synchronous?functions?or?libraries?in?any?async?code.?Django?prevents?you?from?doing?this?with?the?parts?of?Django?that?are?not?async-safe,?but?the?same?may?not?be?true?of?third-party?apps?or?Python?libraries.

Configuring?the?settings?module

When?the?ASGI?server?loads?your?application,?Django?needs?to?import?the?settings?module?—?that’s?where?your?entire?application?is?defined.

Django?uses?the?DJANGO_SETTINGS_MODULE?environment?variable?to?locate?the?appropriate?settings?module.?It?must?contain?the?dotted?path?to?the?settings?module.?You?can?use?a?different?value?for?development?and?production;?it?all?depends?on?how?you?organize?your?settings.

If?this?variable?isn’t?set,?the?default?asgi.py?sets?it?to?mysite.settings,?where?mysite?is?the?name?of?your?project.

Applying?ASGI?middleware

To?apply?ASGI?middleware,?or?to?embed?Django?in?another?ASGI?application,?you?can?wrap?Django’s?application?object?in?the?asgi.py?file.?For?example:

from?some_asgi_library?import?AmazingMiddleware

application?=?AmazingMiddleware(application)

```

全文的意思是匹涮,你需要安裝Daphne天试,然后調(diào)用Django的application來啟動ASGI服務(wù)器∪坏停總結(jié)就以下幾點(diǎn):

?-?不能用?`python?manage.py?runserver`?的方式啟動ASGI服務(wù)器喜每,這只會啟動傳統(tǒng)的、默認(rèn)的WSGI服務(wù)器脚翘,也就是老版本的東西

?-?要啟動ASGI服務(wù)器灼卢,你需要使用Daphne或者Uvicorn。推薦使用Daphne来农,這是Django軟件基金會開發(fā)的一個基于ASGI?(HTTP/WebSocket)的服務(wù)器鞋真。

?-?有一個?`myproject.asgi:application`?文件,是ASGI通信的接口沃于,Django默認(rèn)自帶

????你可以配置?`DJANGO_SETTINGS_MODULE`?環(huán)境涩咖,或者使用默認(rèn)的?`your_project.settings`

??-?可以使用第三方ASGI中間件

我們看看Daphne海诲,點(diǎn)擊Django給的連接,跳轉(zhuǎn)到相關(guān)頁面檩互,內(nèi)容如下:

```

How?to?use?Django?with?Daphne

Daphne?is?a?pure-Python?ASGI?server?for?UNIX,?maintained?by?members?of?the?Django?project.?It?acts?as?the?reference?server?for?ASGI.

Installing?Daphne

You?can?install?Daphne?with?pip:

python?-m?pip?install?daphne

Running?Django?in?Daphne

When?Daphne?is?installed,?a?daphne?command?is?available?which?starts?the?Daphne?server?process.?At?its?simplest,?Daphne?needs?to?be?called?with?the?location?of?a?module?containing?an?ASGI?application?object,?followed?by?what?the?application?is?called?(separated?by?a?colon).

For?a?typical?Django?project,?invoking?Daphne?would?look?like:

daphne?myproject.asgi:application

This?will?start?one?process?listening?on?127.0.0.1:8000.?It?requires?that?your?project?be?on?the?Python?path;?to?ensure?that?run?this?command?from?the?same?directory?as?your?manage.py?file.

```

上述文檔的主要操作步驟如下:

-?`pip?install?daphne`

-?執(zhí)行??`daphne?myproject.asgi:application`?命令特幔,啟動ASGI服務(wù)器

-?瀏覽器訪問?`127.0.0.1:8000`

按照上面的步驟操作,結(jié)果如下:

##?啟動ASGI服務(wù)器

通過?`pip?install?daphne`?即可安裝最新版本的daphne:

```

Collecting?pycparser?(from?cffi!=1.11.3,>=1.8->cryptography>=2.7->autobahn>=0.18->daphne)

Installing?collected?packages:?idna,?hyperlink,?zope.interface,?attrs,?six,?Automat,?constantly,?PyHamcrest,?incremental,?pycparser,?cffi,?cry

ptography,?pyopenssl,?pyasn1,?pyasn1-modules,?service-identity,?twisted,?txaio,?autobahn,?daphne

Successfully?installed?Automat-0.8.0?PyHamcrest-1.9.0?attrs-19.3.0?autobahn-19.11.1?cffi-1.13.2?constantly-15.1.0?cryptography-2.8?daphne-2.4.

0?hyperlink-19.0.0?idna-2.8?incremental-17.5.0?pyasn1-0.4.8?pyasn1-modules-0.2.7?pycparser-2.19?pyopenssl-19.1.0?service-identity-18.1.0?six-1

.13.0?twisted-19.10.0?txaio-18.8.1?zope.interface-4.7.1

```

為了安裝daphne闸昨,需要額外安裝這么多依賴包蚯斯!我們再pip?list看一下:

```bash

(venv)?D:\work\for_test\django3>pip?list

Package??????????Version

----------------?-------

asgiref??????????3.2.3

attrs????????????19.3.0

autobahn?????????19.11.1

Automat??????????0.8.0

cffi?????????????1.13.2

constantly???????15.1.0

cryptography?????2.8

daphne???????????2.4.0

Django???????????3.0

hyperlink????????19.0.0

idna?????????????2.8

incremental??????17.5.0

pip??????????????10.0.1

pyasn1???????????0.4.8

pyasn1-modules???0.2.7

pycparser????????2.19

PyHamcrest???????1.9.0

pyOpenSSL????????19.1.0

pytz?????????????2019.3

service-identity?18.1.0

setuptools???????39.1.0

six??????????????1.13.0

sqlparse?????????0.3.0

Twisted??????????19.10.0

txaio????????????18.8.1

zope.interface???4.7.1

```

安裝成功后,我們會獲得一個`daphne`可執(zhí)行命令饵较,下面我們來啟動服務(wù)器吧拍嵌。

執(zhí)行`daphne?django3.asgi:application`命令,控制臺輸出結(jié)果如下:(將其中的`django3`換成你的工程名字,在`manage.py`文件所在的路徑下執(zhí)行)

```bash

(venv)?D:\work\for_test\django3>daphne?django3.asgi:application

2019-12-04?10:20:07,637?INFO?????Starting?server?at?tcp:port=8000:interface=127.0.0.1

2019-12-04?10:20:07,637?INFO?????HTTP/2?support?not?enabled?(install?the?http2?and?tls?Twisted?extras)

2019-12-04?10:20:07,637?INFO?????Configuring?endpoint?tcp:port=8000:interface=127.0.0.1

2019-12-04?10:20:07,637?INFO?????Listening?on?TCP?address?127.0.0.1:8000

```

當(dāng)然循诉,我們也是可以指定ip和port等參數(shù)的横辆,詳細(xì)請學(xué)習(xí)daphne文檔?`https://pypi.org/project/daphne/`

讀一下啟動信息:

-?默認(rèn)啟動地址是127.0.0.1:8000

-?沒有開啟HTTP/2的支持(需要安裝額外的包)

-?配置了端點(diǎn),開始監(jiān)聽端口

通過瀏覽器來訪問一下吧茄猫!

依然是熟悉的白底火箭圖狈蚤,看起來沒問題。

可是划纽,這是基于HTTP的同步通信脆侮,還不是異步請求!讓我們嘗試一下websocket吧阿浓!

##?嘗試Websocket

瀏覽器中按`F12`進(jìn)入`console`控制臺他嚷,嘗試發(fā)送一個`Websocket`請求:

![在這里插入圖片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly93d3cubGl1amlhbmdibG9nLmNvbS9zdGF0aWMvaW1hZ2VzL2Jsb2cvMTU3NTQyNjYzOTg2MC5wbmc?x-oss-process=image/format,png)忽視前面的css問題,重點(diǎn)在于這個ws請求芭毙,居然無法建立連接!返回狀態(tài)碼500卸耘,也就是服務(wù)器錯誤退敦!

再看看Pycharm后臺的信息:

```bash

127.0.0.1:5991?-?-?[04/Dec/2019:10:30:05]?"WSCONNECTING?/"?-?-

2019-12-04?10:30:05,246?ERROR????Exception?inside?application:?Django?can?only?handle?ASGI/HTTP?connections,?not?websocket.

??File?"d:\work\for_test\django3\venv\lib\site-packages\daphne\cli.py",?line?30,?in?asgi

????await?self.app(scope,?receive,?send)

??File?"d:\work\for_test\django3\venv\lib\site-packages\django\core\handlers\asgi.py",?line?146,?in?__call__

????%?scope['type']

??Django?can?only?handle?ASGI/HTTP?connections,?not?websocket.

127.0.0.1:5991?-?-?[04/Dec/2019:10:30:05]?"WSDISCONNECT?/"?-?-

```

重點(diǎn)在這句?``Django?can?only?handle?ASGI/HTTP?connections,?not?websocket.``

什么?Django不支持Websocket蚣抗?說好的ASGI侈百,說好的全雙工異步通信呢?

難道是我哪里搞錯了翰铡?不行钝域,我得看看源碼去!

##?Django3.0的源碼

一路點(diǎn)點(diǎn)點(diǎn)锭魔,翻了個遍例证,發(fā)現(xiàn)Django3.0與之前的2.2關(guān)于ASGI的區(qū)別就是多了下面兩個文件:

![在這里插入圖片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly93d3cubGl1amlhbmdibG9nLmNvbS9zdGF0aWMvaW1hZ2VzL2Jsb2cvMTU3NTQyNzEwNDcyMi5wbmc?x-oss-process=image/format,png)

`django.core.asgi`很簡單,一看就懂迷捧,如下所是:

```python

import?django

from?django.core.handlers.asgi?import?ASGIHandler

def?get_asgi_application():

????django.setup(set_prefix=False)

????return?ASGIHandler()

```

關(guān)鍵是`django.core.handlers.asgi`這個文件织咧,不到300行胀葱,總共就2個類,代碼就不貼了:

-?ASGIRequest:繼承了HttpRequest類笙蒙,一看就知道是構(gòu)造請求對象

-?ASGIHandler:繼承了base.BaseHandler抵屿,這個就類似WSGIHandler,用于具體處理ASGI請求

讓我們看看它的其中一段代碼:

```python

#?Serve?only?HTTP?connections.

#?FIXME:?Allow?to?override?this.

if?scope['type']?!=?'http':

????raise?ValueError(

????????'Django?can?only?handle?ASGI/HTTP?connections,?not?%s.'

????????%?scope['type']

????)

```

這就是我們前面在瀏覽器中發(fā)送ws請求捅位,但是無法建立連接的原因轧葛!

如果`scope`的`type`屬性不是`http`,那么彈出`ValueError`異常艇搀,并提示不支持該類連接朝群!

再看看人家寫的注釋,明明白白的寫著`Serve?only?HTTP?connections.?FIXME:?Allow?to?override?this.`中符。翻譯過來就是只支持HTTP連接姜胖,請自己重寫這部分內(nèi)容修復(fù)這個缺陷。FIXME淀散!FIXME右莱!

##?總結(jié)

與Django3.0關(guān)于異步通信的初體驗(yàn)很不好,Django真的目前只提供了個接口档插,內(nèi)部實(shí)現(xiàn)還沒做

由于相關(guān)資料太少慢蜓,多方查找,據(jù)說:

????Django會在后續(xù)的版本陸續(xù)實(shí)現(xiàn)完整的原生的異步通信能力郭膛,從同步機(jī)制切換到可兼容的異步機(jī)制

????目前3.0階段晨抡,要與websocket通信依然得通過`django-channel`庫,還不是原生支持

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末则剃,一起剝皮案震驚了整個濱河市耘柱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌棍现,老刑警劉巖调煎,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異己肮,居然都是意外死亡士袄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門谎僻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娄柳,“玉大人,你說我怎么就攤上這事艘绍〕嗑埽” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵鞍盗,是天一觀的道長需了。 經(jīng)常有香客問我跳昼,道長,這世上最難降的妖魔是什么肋乍? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任鹅颊,我火速辦了婚禮,結(jié)果婚禮上墓造,老公的妹妹穿的比我還像新娘堪伍。我一直安慰自己,他們只是感情好觅闽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布帝雇。 她就那樣靜靜地躺著,像睡著了一般蛉拙。 火紅的嫁衣襯著肌膚如雪尸闸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天孕锄,我揣著相機(jī)與錄音吮廉,去河邊找鬼。 笑死畸肆,一個胖子當(dāng)著我的面吹牛宦芦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轴脐,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼调卑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了大咱?” 一聲冷哼從身側(cè)響起恬涧,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎徽级,沒想到半個月后气破,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡餐抢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了低匙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旷痕。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖顽冶,靈堂內(nèi)的尸體忽然破棺而出欺抗,到底是詐尸還是另有隱情,我是刑警寧澤强重,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布绞呈,位于F島的核電站贸人,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏佃声。R本人自食惡果不足惜艺智,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望圾亏。 院中可真熱鬧十拣,春花似錦、人聲如沸志鹃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽曹铃。三九已至缰趋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陕见,已是汗流浹背秘血。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淳玩,地道東北人直撤。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像蜕着,于是被迫代替她去往敵國和親谋竖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容