step1:創(chuàng)建模型
step2:創(chuàng)建一個(gè)Serializer類
? ? ? ? 開(kāi)始使用Web API的第一件事是提供一種將代碼片段實(shí)例序列化和反序列化為表示形式(如json)的方法。?
? ??????使用ModelSerializers:與Django提供的Form類和ModelForm類一樣,REST框架包括Serializer類和ModelSerializer類

? ? ? ? ModelSerializer類不會(huì)做任何特別神奇的事情,它們只是創(chuàng)建序列化器類的快捷方式:
? ? ? ? ? ? 1、一組自動(dòng)確定的字段。
? ? ? ? ????2、create()和update()方法的簡(jiǎn)單的實(shí)現(xiàn)。
請(qǐng)求和響應(yīng)
????????1、請(qǐng)求對(duì)象
????????REST框架引入了Request擴(kuò)展常規(guī)的對(duì)象HttpRequest,并提供更靈活的請(qǐng)求解析。Request對(duì)象的核心功能是request.data屬性,這與request.POST使用Web API?相似但更有用。
? ??????request.POST??#?Only?handles?form?data.??Only?works?for?'POST'?method.
????????request.data??#?Handles?arbitrary?data.??Works?for?'POST',?'PUT'?and?'PATCH'?methods.
????????2、響應(yīng)對(duì)象
????????REST框架還引入了一個(gè)Response對(duì)象,它是一種類型的對(duì)象,它TemplateResponse采用未呈現(xiàn)的內(nèi)容,并使用內(nèi)容協(xié)商來(lái)確定正確的內(nèi)容類型以返回給客戶端。
????????return?Response(data)??#?Renders?to?content?type?as?requested?by?the?client.
????????3、狀態(tài)碼
? ? ? ? REST框架為每一個(gè)狀態(tài)碼更明確的標(biāo)識(shí)符,如HTTP_400_BAD_REQUEST所述的status模塊。相對(duì)于使用數(shù)字標(biāo)識(shí)符更好。
????????4、包裝API視圖
????????REST框架提供了兩個(gè)可用于編寫(xiě)API視圖的包裝器。
? ? ? ? (1)@api_view用于使用基于功能的視圖的裝飾器。
? ? ? ? (2)繼承APIView的基于類的視圖工作。
????????這些包裝器提供了一些功能,例如確保您Request在視圖中接收實(shí)例,并將上下文添加到Response對(duì)象,以便可以執(zhí)行內(nèi)容協(xié)商。
????????包裝器還提供405 Method Not Allowed適當(dāng)?shù)姆祷仨憫?yīng)等行為,以及處理使用格式不正確的輸入ParseError訪問(wèn)時(shí)發(fā)生的任何異常request.data。
step3、視圖
(1)基于函數(shù)的視圖


????????我們不再明確地將我們的請(qǐng)求或響應(yīng)明確綁定到給定的內(nèi)容類型。?request.data可以處理傳入的json請(qǐng)求,但它也可以處理其他格式。類似地,我們使用數(shù)據(jù)返回響應(yīng)對(duì)象,但允許REST框架將響應(yīng)呈現(xiàn)給正確的內(nèi)容類型。
向我們的網(wǎng)址添加可選的格式后綴
????????為了使我們的響應(yīng)不再限于單一的內(nèi)容類型,我們可以為API端點(diǎn)添加對(duì)格式后綴的支持。使用格式后綴給我們明確指定給定格式的URL,這意味著我們的API將能夠處理諸如http://example.com/api/items/4.json之類的?URL?。
? ? ? ? (1)、首先f(wàn)ormat在兩個(gè)視圖中添加一個(gè)關(guān)鍵字參數(shù),就像這樣。

? ? ? ? (2)、在urls.py稍稍更新文件,format_suffix_patterns除了現(xiàn)有的URL之外還附加一組。

(2)基于類的視圖



(3)使用mixin來(lái)實(shí)現(xiàn)視圖
????????到目前為止,我們使用的創(chuàng)建/檢索/更新/刪除操作對(duì)于我們創(chuàng)建的任何模型支持的API視圖將非常相似。 這些常見(jiàn)的行為是在REST框架的mixin類中實(shí)現(xiàn)的。

???????用GenericAPIView創(chuàng)建一個(gè)視圖,并添加ListModelMixin和CreateModelMixin,到目前為止足夠簡(jiǎn)單?;愄峁┖诵墓δ埽?b>mixin類提供.list()和.create()操作。我們明確的將get和post方法綁定到適當(dāng)?shù)牟僮?/b>上。

????????我們?cè)俅问褂肎enericAPIView類來(lái)提供核心功能,并在mixin中添加.retrieve(),.update()和.destroy()方法。
(4)使用通用的基于類的視圖

step4、權(quán)限驗(yàn)證
????????目前,我們的API對(duì)誰(shuí)可以編輯或刪除代碼段沒(méi)有任何限制。我們想要一些更高級(jí)的行為:
????????代碼段始終與創(chuàng)建者相關(guān)聯(lián)。
????????只有身份驗(yàn)證的用戶可以創(chuàng)建片段。
????????只有片段的創(chuàng)建者可以更新或刪除它。
????????未經(jīng)身份驗(yàn)證的請(qǐng)求應(yīng)具有完全只讀訪問(wèn)權(quán)限。
? ??????1、將用戶信息添加到我們的模型
????????我們將對(duì)我們的Snippet模型類進(jìn)行一些更改。首先,我們添加幾個(gè)字段。其中一個(gè)字段將用于表示創(chuàng)建代碼段的用戶。另一個(gè)字段將用于存儲(chǔ)代碼的突出顯示的HTML表示。

? ??????2、為用戶模型添加端點(diǎn)
????????現(xiàn)在我們有一些用戶可以使用,我們最好將這些用戶的表示添加到我們的API中。創(chuàng)建一個(gè)新的serializer很容易。在serializers.py添加:

????????因?yàn)樵赨ser模型上'snippets'是一個(gè)反向關(guān)系,所以在使用ModelSerializer該類時(shí)它不會(huì)被默認(rèn)包含,所以我們需要為它添加一個(gè)顯式字段。
? ??3、將片段與用戶關(guān)聯(lián)
????????現(xiàn)在,如果我們創(chuàng)建了一個(gè)代碼片段,那么將無(wú)法將創(chuàng)建該代碼段的用戶與代碼段實(shí)例相關(guān)聯(lián)。用戶不是作為序列化表示的一部分發(fā)送的,而是傳入請(qǐng)求的屬性。
????????我們處理的方式是覆蓋.perform_create()我們的代碼片段視圖上的方法,這樣我們可以修改實(shí)例保存的管理方式,并處理傳入請(qǐng)求或請(qǐng)求的URL中隱含的任何信息。
????????在SnippetList視圖類中,添加以下方法:

4、更新serializer
????????現(xiàn)在,這些片段與創(chuàng)建它們的用戶相關(guān)聯(lián),我們更新我們SnippetSerializer來(lái)反映這一點(diǎn)。將以下字段添加到序列化器定義中serializers.py:

? ??????確保您還添加'owner',到內(nèi)部Meta類的字段列表。
????????這個(gè)領(lǐng)域正在做一些很有趣的事情。source的那個(gè)屬性參數(shù)控制用于填充的字段,并且可以在對(duì)串行化實(shí)例的任何屬性點(diǎn)。它也可以采用上面顯示的點(diǎn)劃線,在這種情況下,它將以與Django模板語(yǔ)言一起使用的相似方式遍歷給定的屬性。
????????我們添加了字段是類型化ReadOnlyField類,相對(duì)于其他類型的字段,如CharField,BooleanField等...類型化ReadOnlyField始終是只讀的,并且將用于序列化表示形式,但不會(huì)被用于更新模型他們被反序列化的實(shí)例。我們也可以CharField(read_only=True)在這里使用。
5、添加視圖所需的權(quán)限
????????現(xiàn)在,代碼片段與用戶相關(guān)聯(lián),我們希望確保只有經(jīng)過(guò)身份驗(yàn)證的用戶才能創(chuàng)建,更新和刪除代碼段。
????????REST框架包括許多權(quán)限類,我們可以使用它們來(lái)限制誰(shuí)可以訪問(wèn)給定的視圖。在這種情況下,我們正在尋找的是IsAuthenticatedOrReadOnly,這將確保經(jīng)過(guò)身份驗(yàn)證的請(qǐng)求獲得讀寫(xiě)訪問(wèn)權(quán)限,未經(jīng)身份驗(yàn)證的請(qǐng)求將獲得只讀訪問(wèn)權(quán)限。

????????如果您打開(kāi)瀏覽器并導(dǎo)航到目前可瀏覽的API,那么您將發(fā)現(xiàn)無(wú)法再創(chuàng)建新的代碼段。為了做到這一點(diǎn),我們需要能夠以用戶身份登錄。
????????我們可以通過(guò)編輯項(xiàng)目級(jí)urls.py文件中的URLconf來(lái)添加可瀏覽API使用的登錄視圖。

????????r'^api-auth/'模式的一部分實(shí)際上可以是您要使用的任何URL。唯一的限制是所包含的URL必須使用'rest_framework'命名空間。
7、對(duì)象級(jí)權(quán)限
????????我們希望所有的代碼片段都可以被任何人看到,但也要確保只有創(chuàng)建代碼段的用戶才能更新或刪除它。要做到這一點(diǎn),我們將需要?jiǎng)?chuàng)建一個(gè)自定義權(quán)限。
????????在片段應(yīng)用中,創(chuàng)建一個(gè)新文件,permissions.py

????????現(xiàn)在,我們可以通過(guò)編輯視圖類中的permission_classes屬性將該自定義權(quán)限添加到我們的代碼段實(shí)例端點(diǎn)SnippetDetail:

????????現(xiàn)在,如果再次打開(kāi)瀏覽器,您會(huì)發(fā)現(xiàn)如果您以與創(chuàng)建代碼段相同的用戶身份登錄,“DELETE”和“PUT”操作只會(huì)顯示在代碼段實(shí)例端點(diǎn)上。
8、使用API進(jìn)行身份驗(yàn)證
????????因?yàn)槲覀儸F(xiàn)在有一組API的權(quán)限,如果我們要編輯任何片段,我們需要驗(yàn)證我們的請(qǐng)求。我們還沒(méi)有設(shè)置任何身份驗(yàn)證類,所以默認(rèn)值現(xiàn)在被應(yīng)用,哪些是SessionAuthentication和BasicAuthentication。
????????當(dāng)我們通過(guò)Web瀏覽器與API進(jìn)行交互時(shí),我們可以登錄,然后瀏覽器會(huì)話將為請(qǐng)求提供所需的身份驗(yàn)證。
????????如果我們以編程方式與API交互,我們需要在每個(gè)請(qǐng)求上顯式提供身份驗(yàn)證憑據(jù)。
????????如果我們嘗試創(chuàng)建一個(gè)沒(méi)有驗(yàn)證的代碼段,我們會(huì)收到一個(gè)錯(cuò)誤:

step5、ViewSets&Routers
????????REST框架包括一個(gè)處理的抽象ViewSets,它允許開(kāi)發(fā)人員集中精力對(duì)API的狀態(tài)和交互進(jìn)行建模,并根據(jù)常規(guī)約定使URL構(gòu)造自動(dòng)處理。
????????ViewSet類是幾乎同樣的事情View類,但他們提供諸如操作read,或者update,而不是方法處理,如get或put。
????????一個(gè)ViewSet類在最后一刻被綁定到一組方法處理程序,當(dāng)它被實(shí)例化成一組視圖時(shí),通常通過(guò)使用一個(gè)Router類來(lái)處理為你定義URL conf的復(fù)雜性。
1、我們來(lái)看一下我們目前的view,并把它們重構(gòu)成視圖集。
????????首先,讓我們來(lái)重構(gòu)我們UserList和UserDetail View納入一個(gè)單一的UserViewSet。我們可以刪除這兩個(gè)視圖,并將其替換為單個(gè)類:

????????在這里,我們使用ReadOnlyModelViewSet該類來(lái)自動(dòng)提供默認(rèn)的“只讀”操作。我們?nèi)匀徽缥覀兪褂贸R?guī)視圖一樣設(shè)置queryset和serializer_class屬性,但是我們不再需要向兩個(gè)不同的類提供相同的信息。
????????接下來(lái)我們要更換SnippetList,SnippetDetail和SnippetHighlight視圖類。我們可以刪除三個(gè)視圖,并再次替換為單個(gè)類。

????????這一次,我們已經(jīng)使用了ModelViewSet類來(lái)獲取完整的默認(rèn)讀寫(xiě)操作。
????????請(qǐng)注意,我們還使用@detail_route裝飾器創(chuàng)建一個(gè)名為的自定義操作highlight。此裝飾器可用于添加不適合標(biāo)準(zhǔn)create/update/delete樣式的任何自定義端點(diǎn)。
????????默認(rèn)情況下,使用@detail_route裝飾器的自定義操作將響應(yīng)GET請(qǐng)求。methods如果我們想要一個(gè)響應(yīng)POST請(qǐng)求的動(dòng)作,我們可以使用該參數(shù)。
????????默認(rèn)情況下,自定義操作的URL取決于方法名稱本身。如果要更改url應(yīng)該構(gòu)造的方式,可以將url_path作為decorator的關(guān)鍵字參數(shù)。
2、明確地將ViewSets綁定到URL
????????當(dāng)我們定義URLConf時(shí),處理程序方法只會(huì)被綁定到動(dòng)作上。看看發(fā)生什么事情,讓我們首先從ViewSets中明確創(chuàng)建一組視圖。
????????在urls.py文件中,我們將我們的ViewSet類綁定到一組具體的視圖中。

????????請(qǐng)注意,我們?nèi)绾蜼iewSet通過(guò)將http方法綁定到每個(gè)視圖所需的操作,從每個(gè)類創(chuàng)建多個(gè)視圖。
????????現(xiàn)在我們將資源綁定到具體的視圖中,我們可以像往常一樣使用URL conf注冊(cè)視圖。

3.使用路由器
????????因?yàn)槲覀?b>使用ViewSet類而不是View類,我們實(shí)際上不需要設(shè)計(jì)自己的URL。將資源連接到視圖和網(wǎng)址的約定可以使用Router類自動(dòng)處理。我們需要做的就是使用路由器注冊(cè)相應(yīng)的視圖集,然后讓它執(zhí)行其余操作。
????????這是我們的重新連線的urls.py文件。

????????與路由器注冊(cè)視圖與提供urlpattern類似。我們包括兩個(gè)參數(shù):視圖的URL前綴和視圖本身。
DefaultRouter我們使用的類也會(huì)自動(dòng)為我們創(chuàng)建API根視圖,因此我們現(xiàn)在可以api_root從我們的views模塊中刪除該方法。