1. 程式人生 > >18.DjangoRestFramework學習一之restful規範、APIview、解析器元件、Postman等

18.DjangoRestFramework學習一之restful規範、APIview、解析器元件、Postman等

一 預備知識

  預備知識:django的CBV和FBV

    CBV(class based view):多用,簡單回顧一下

    FBV(function based view):

  CBV模式的簡單操作:來個登陸頁面吧

  login.html檔案內容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="{% url 'login' %}" method="post">
    {% csrf_token %}
    使用者名稱: <input type="text" name="username">
    密碼: <input type="text" name="password">
    <input type="submit">
</form>


</body>
</html>

  url.py內容如下

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.LoginView.as_view(),name='login'),
]

  views.py

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
from django.views import View

class LoginView(View):

    def get(self,request):

        return render(request,'login.html')
    def post(self,request):

        return HttpResponse('post')

  大家還記得CBV的這個檢視函式,為什麼get請求就能找到類的get方法,post請求就能找到post方法,其內部有個dispatch方法來進行分發,這又怎麼玩呢,看原始碼啦,從哪裡看呢?那裡先執行,就從哪裡看

  views.LoginView.as_view()這個東西是不是先執行啊,url接收到請求,呼叫了它對不對,as_view()類方法,這個類方法給你返回了一個叫view的方法,就是說這個url對應這個一個view方法,當用戶訪問login頁面的時候是不是就是執行了view(request),大家進去看看原始碼吧。

  然後你就可以玩dispatch方法了,看程式碼:

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
from django.views import View

class LoginView(View):

    def dispatch(self, request, *args, **kwargs):
        print('something...')
        res = super().dispatch(request, *args, **kwargs) #注意,不用傳self,為什麼呢,因為super已經幫你吧self放進去啦
        print('someting....')
        return res

    def get(self,request):

        return render(request,'login.html')
    def post(self,request):

        return HttpResponse('post')

  為什麼要說它呢,因為後面咱們的drf學習,就要用它啦。

二 restful規範

  摘自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html

  1. 什麼是RESTFUl

    RESTful 是目前最流行的 API 設計規範,用於 Web 資料介面的設計。

    REST與技術無關,代表的是一種軟體架構風格,REST是Representational State Transfer的簡稱,中文翻譯為“表徵狀態轉移”

    REST從資源的角度類審視整個網路,它將分佈在網路中某個節點的資源通過URL進行標識,客戶端應用通過URL來獲取資源的表徵,獲得這些表徵致使這些應用轉變狀態

    所有的資料,不過是通過網路獲取的還是操作(增刪改查)的資料,都是資源,將一切資料視為資源是REST區別與其他架構風格的最本質屬性

    對於REST這種面向資源的架構風格,有人提出一種全新的結構理念,即:面向資源架構(ROA:Resource Oriented Architecture)

      另外還有其他兩種,簡單瞭解。

遠端過程呼叫(RPC)
遠端過程呼叫為 Web 服務提供一個分散式函式/方法介面供使用者呼叫。這是一種較傳統的方式。通常,在 WSDL 中對 RPC 介面進行定義(類似於早期的XML-RPC)。本質上,RPC 方式利用一個簡單對映,把使用者請求直接轉化成一個特定語言編寫的函式/方法。現在,該方式已不再使用。

面向服務架構(SOA)
面向服務架構現在,業界比較關注的是遵從面向服務架構(Service-oriented architecture,SOA)來構建 Web 服務。該方式中,通訊是由訊息驅動,而不再是某個動作(方法呼叫)。這種 Web 服務也稱為“面向訊息的服務”。

    網路應用程式,分為前端和後端兩個部分。當前的發展趨勢,就是前端裝置層出不窮(手機、平板、桌面電腦、其他專用裝置......)。

    因此,必須有一種統一的機制,方便不同的前端裝置與後端進行通訊。這導致API構架的流行,甚至出現"API First"的設計思想。RESTful API是目前比較成熟的一套網際網路應用程式的API設計理論。還有一篇《理解RESTful架構》,探討如何理解這個概念。

    表徵狀態轉移大概圖解:

      

    

  2.RESTFUl API設計

    2.1 使用協議

      API與使用者的通訊協議,總是使用HTTPs協議。

    2.2 使用域名

      應該儘量將API部署在專用域名之下,意思就是給API專門做一個伺服器。

https://api.example.com

      如果確定API很簡單,不會有進一步擴充套件,可以考慮放在主域名下。

https://example.org/api/

    2.3 版本提示

      網站的API可能一直在更新,那麼應該將API的版本號放入URL。

https://api.example.com/v1/

      另一種做法是,將版本號放在HTTP頭資訊中,但不如放入URL方便和直觀。Github採用這種做法。

    2.4 路徑寫法   

      路徑又稱"終點"(endpoint),表示API的具體網址。

      在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與資料庫的表格名對應。一般來說,資料庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應該使用複數。

      舉例來說,有一個API提供動物園(zoo)的資訊,還包括各種動物和僱員的資訊,則它的路徑應該設計成下面這樣。

https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees

    2.5 HTTP動詞

      對於資源的具體操作型別,由HTTP動詞表示,請求方式時動詞,我們後端基於請求方式來分發對應的檢視函式來進行邏輯處理和資料處理、提取、加工等操作,但是URL中不能出現動詞。

      常用的HTTP動詞有下面五個(括號裡是對應的SQL命令)。

GET(SELECT):從伺服器取出資源(一項或多項)。
POST(CREATE):在伺服器新建一個資源。
PUT(UPDATE):在伺服器更新資源(客戶端提供改變後的完整資源)。
PATCH(UPDATE):在伺服器更新資源(客戶端提供改變的屬性,更新部分資源的意思)。他和put用哪個都可以,沒有太大的區別,我們用put方式偏多
DELETE(DELETE):從伺服器刪除資源。

      還有兩個不常用的HTTP動詞。

HEAD:獲取資源的元資料。
OPTIONS:獲取資訊,關於資源的哪些屬性是客戶端可以改變的

      下面是一些例子。RESTful 的核心思想就是,客戶端發出的資料操作指令都是"動詞 + 賓語"的結構。比如,GET /articles這個命令,GET是動詞,/articles是賓語。根據 HTTP 規範,動詞一律大寫。

GET /zoos:列出所有動物園
POST /zoos:新建一個動物園
GET /zoos/ID:獲取某個指定動物園的資訊
PUT /zoos/ID:更新某個指定動物園的資訊(提供該動物園的全部資訊)
PATCH /zoos/ID:更新某個指定動物園的資訊(提供該動物園的部分資訊)
DELETE /zoos/ID:刪除某個動物園
GET /zoos/ID/animals:列出某個指定動物園的所有動物
DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物

      動詞覆蓋:       

        有些客戶端只能使用GETPOST這兩種方法。伺服器必須接受POST模擬其他三個方法(PUTPATCHDELETE)。

        這時,客戶端發出的 HTTP 請求,要加上X-HTTP-Method-Override屬性,告訴伺服器應該使用哪一個動詞,覆蓋POST方法。

POST /api/Person/4 HTTP/1.1  
X-HTTP-Method-Override: PUT

        上面程式碼中,X-HTTP-Method-Override指定本次請求的方法是PUT,而不是POST

      賓語必須是名字:

        賓語就是 API 的 URL,是 HTTP 動詞作用的物件。它應該是名詞,不能是動詞。比如,/articles這個 URL 就是正確的,而下面的 URL 不是名詞,所以都是錯誤的。

/getAllCars
/createNewCar
/deleteAllRedCars

        既然 URL 是名詞,那麼應該使用複數,還是單數?

        這沒有統一的規定,但是常見的操作是讀取一個集合,比如GET /articles(讀取所有文章),這裡明顯應該是複數。

        為了統一起見,建議都使用複數 URL,比如GET /articles/2要好於GET /article/2

        

    2.6 過濾資訊(filtering,或稱查詢引數)

      如果記錄數量很多,伺服器不可能都將它們返回給使用者。API應該提供引數,過濾返回結果。

      下面是一些常見的引數。

?limit=10:指定返回記錄的數量
?offset=10:指定返回記錄的開始位置。
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。
?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序。
?animal_type_id=1:指定篩選條件

      引數的設計允許存在冗餘,即允許API路徑和URL引數偶爾有重複。比如,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。

      常見的情況是,資源需要多級分類,因此很容易寫出多級的 URL,比如獲取某個作者的某一類文章。

GET /authors/12/categories/2

      這種 URL 不利於擴充套件,語義也不明確,往往要想一會,才能明白含義。

      更好的做法是,除了第一級,其他級別都用查詢字串表達。

GET /authors/12?categories=2

      下面是另一個例子,查詢已釋出的文章。你可能會設計成下面的 URL。

GET /articles/published

      查詢字串的寫法明顯更好

GET /articles?published=true

    2.7 狀態碼

      2.7.1 狀態碼必須精確

        客戶端的每一次請求,伺服器都必須給出迴應。迴應包括 HTTP 狀態碼和資料兩部分。

        HTTP 狀態碼就是一個三位數,分成五個類別。

1xx:相關資訊
2xx:操作成功
3xx:重定向
4xx:客戶端錯誤
5xx:伺服器錯誤

        這五大類總共包含100多種狀態碼,覆蓋了絕大部分可能遇到的情況。每一種狀態碼都有標準的(或者約定的)解釋,客戶端只需檢視狀態碼,就可以判斷出發生了什麼情況,所以伺服器應該返回儘可能精確的狀態碼。

        API 不需要1xx狀態碼,下面介紹其他四類狀態碼的精確含義。

      2.7.2 2xx狀態碼

        200狀態碼錶示操作成功,但是不同的方法可以返回更精確的狀態碼。

GET: 200 OK
POST: 201 Created
PUT: 200 OK
PATCH: 200 OK
DELETE: 204 No Content

        上面程式碼中,POST返回201狀態碼,表示生成了新的資源;DELETE返回204狀態碼,表示資源已經不存在。

        此外,202 Accepted狀態碼錶示伺服器已經收到請求,但還未進行處理,會在未來再處理,通常用於非同步操作。下面是一個例子。

HTTP/1.1 202 Accepted

{
  "task": {
    "href": "/api/company/job-management/jobs/2130040",
    "id": "2130040"
  }
}

      2.7.3 3xx狀態碼

        API 用不到301狀態碼(永久重定向)和302狀態碼(暫時重定向,307也是這個含義),因為它們可以由應用級別返回,瀏覽器會直接跳轉,API 級別可以不考慮這兩種情況。

        API 用到的3xx狀態碼,主要是303 See Other,表示參考另一個 URL。它與302307的含義一樣,也是"暫時重定向",區別在於302307用於GET請求,而303用於POSTPUTDELETE請求。收到303以後,瀏覽器不會自動跳轉,而會讓使用者自己決定下一步怎麼辦。下面是一個例子。

HTTP/1.1 303 See Other
Location: /api/orders/12345

      2.7.4 4xx狀態碼

        4xx狀態碼錶示客戶端錯誤,主要有下面幾種。

400 Bad Request:伺服器不理解客戶端的請求,未做任何處理。

401 Unauthorized:使用者未提供身份驗證憑據,或者沒有通過身份驗證。

403 Forbidden:使用者通過了身份驗證,但是不具有訪問資源所需的許可權。

404 Not Found:所請求的資源不存在,或不可用。

405 Method Not Allowed:使用者已經通過身份驗證,但是所用的 HTTP 方法不在他的許可權之內。

410 Gone:所請求的資源已從這個地址轉移,不再可用。

415 Unsupported Media Type:客戶端要求的返回格式不支援。比如,API 只能返回 JSON 格式,但是客戶端要求返回 XML 格式。

422 Unprocessable Entity :客戶端上傳的附件無法處理,導致請求失敗。

429 Too Many Requests:客戶端的請求次數超過限額。

      2.7.5 5xx狀態碼

        5xx狀態碼錶示服務端錯誤。一般來說,API 不會向用戶透露伺服器的詳細資訊,所以只要兩個狀態碼就夠了。

500 Internal Server Error:客戶端請求有效,伺服器處理時發生了意外。

503 Service Unavailable:伺服器無法處理請求,一般用於網站維護狀態。

      總結一下常用狀態碼及對應的描述

200 OK - [GET]:伺服器成功返回使用者請求的資料,該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:使用者新建或修改資料成功。
202 Accepted - [*]:表示一個請求已經進入後臺排隊(非同步任務)
204 NO CONTENT - [DELETE]:使用者刪除資料成功。301  狀態碼(永久重定向)302  狀態碼(暫時重定向,307也是這個含義)
400 INVALID REQUEST - [POST/PUT/PATCH]:使用者發出的請求有錯誤,伺服器沒有進行新建或修改資料的操作,該操作是冪等的。
401 Unauthorized - [*]:表示使用者沒有許可權(令牌、使用者名稱、密碼錯誤)。
403 Forbidden - [*] 表示使用者得到授權(與401錯誤相對),但是訪問是被禁止的。
404 NOT FOUND - [*]:使用者發出的請求針對的是不存在的記錄,伺服器沒有進行操作,該操作是冪等的。
406 Not Acceptable - [GET]:使用者請求的格式不可得(比如使用者請求JSON格式,但是隻有XML格式)。
410 Gone -[GET]:使用者請求的資源被永久刪除,且不會再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個物件時,發生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:伺服器發生錯誤,使用者將無法判斷髮出的請求是否成功。

更多看這裡:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

    2.8 伺服器響應

      2.8.1 響應資料格式

        API 返回的資料格式,不應該是純文字,而應該是一個 JSON 物件,因為這樣才能返回標準的結構化資料。所以,伺服器迴應的 HTTP 頭的Content-Type屬性要設為application/json

        客戶端請求時,也要明確告訴伺服器,可以接受 JSON 格式,即請求的 HTTP 頭的ACCEPT屬性也要設成application/json。下面是一個例子。

GET /orders/2 HTTP/1.1 
Accept: application/json

      2.8.2 發生錯誤時的響應

        發生錯誤時不要響應200狀態碼,有一種不恰當的做法是,即使發生錯誤,也返回200狀態碼,把錯誤資訊放在資料體裡面,就像下面這樣。

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "failure",
  "data": {
    "error": "Expected at least two items in list."
  }
}

        上面程式碼中,解析資料體以後,才能得知操作失敗。

        這張做法實際上取消了狀態碼,這是完全不可取的。正確的做法是,狀態碼反映發生的錯誤,具體的錯誤資訊放在資料體裡面返回。下面是一個例子。

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Invalid payoad.",
  "detail": {
     "surname": "This field is required."
  }
}

      2.8.3 響應結果

        針對不同操作,伺服器向用戶返回的結果應該符合以下規範。

GET /collection:返回資源物件的列表(陣列),一般是[{"id":1,"name":"a",},{"id":2,name:"b"},]這種型別
GET /collection/resource:返回單個資源物件, 一般是檢視的單條資料 {"id":1,"name":'a'}
POST /collection:返回新生成的資源物件 , 一般是返回新新增的資料資訊, 格式一般是{}
PUT /collection/resource:返回完整的資源物件  一般時返回更新後的資料,{}
PATCH /collection/resource:返回完整的資源物件
DELETE /collection/resource:返回一個空文件  一般返回一個空字串

        例如:  

        

    2.9 Hypermedia API,提供連結

      RESTful API最好做到Hypermedia,即返回結果中提供連結,API 的使用者未必知道,URL 是怎麼設計的。一個解決方法就是,在迴應中,給出相關連結,便於下一步操作。這樣的話,使用者只要記住一個 URL,就可以發現其他的 URL。這種方法叫做 HATEOAS。

      舉例來說,GitHub 的 API 都在 api.github.com 這個域名。訪問它,就可以得到其他 URL。

{
  ...
  "feeds_url": "https://api.github.com/feeds",
  "followers_url": "https://api.github.com/user/followers",
  "following_url": "https://api.github.com/user/following{/target}",
  "gists_url": "https://api.github.com/gists{/gist_id}",
  "hub_url": "https://api.github.com/hub",
  ...
}

      上面的迴應中,挑一個 URL 訪問,又可以得到別的 URL。對於使用者來說,不需要記住 URL 設計,只要從 api.github.com 一步步查詢就可以了。

      HATEOAS 的格式沒有統一規定,上面例子中,GitHub 將它們與其他屬性放在一起。更好的做法應該是,將相關連結與其他屬性分開。

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "In progress",
   "links": {[
    { "rel":"cancel", "method": "delete", "href":"/api/status/12345" } ,
    { "rel":"edit", "method": "put", "href":"/api/status/12345" }
  ]}
}

      再比如:當用戶向api.example.com的根目錄發出請求,會得到這樣一個文件。

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

      上面程式碼表示,文件中有一個links屬性,使用者讀取這個屬性就知道下一步該呼叫什麼API了。rel表示這個API與當前網址的關係(collection關係,並給出該collection的網址),href表示API的路徑,title表示API的標題,type表示返回型別。

    2.10 其他

      (1)API的身份認證應該使用OAuth 2.0框架。

      (2)伺服器返回的資料格式,應該儘量使用JSON,避免使用XML。

三 Django RestFramework(簡稱DRF)

drf是django發展來的一個符合restful介面規範的一個東西,啥東西呢,就是django的一個app,還記得app是啥不。DRF官網地址,但是大家記住一句話,即便是沒有這drf,我們照樣能做前後端分離的專案,自己做規範的資料介面,返回json資料,都是沒問題的昂,那為什麼還用drf啊,這個更nb。

在官網中我們看一下這裡:

  

首先下載安裝,django是必須要的,不過咱們的django已經下載好了,如果沒下載好,那麼pip install django,執行一下:

pip install django
pip install djangorestframework  //執行這句話,下載drf

# Set up a new project with a single application
django-admin startproject tutorial .  # Note the trailing '.' character
cd tutorial
django-admin startapp quickstart
cd ..

1.先基於djangoCBV,不用DRF來寫個介面,看看效果

  好,接下來我們建立一個django專案,models中建立一個表,新增一些資料,然後寫一個數據介面來獲取一下這些資料,返回json資料型別,按照我們CBV的模式來寫,但是下面還沒有用到我們的drf昂,只是告訴大家,沒有drf,你也能做。

    

      

  

  views.py檔案內容如下:

from django.shortcuts import render,HttpResponse,redirect
import json
# Create your views here.
from django.views import View
from app01 import models
class CourseView(View):

    def get(self,request):
        #拿到queryset型別的資料,要加工成[{},{}]這種資料型別
        course_obj_list = models.Course.objects.all()
        ret = []
        for course_obj in course_obj_list:
            ret.append({
                "title":course_obj.title,
                "desc":course_obj.desc,
            })

        return HttpResponse(json.dumps(ret,ensure_ascii=False)) #ensure_ascii=False是告訴json不要對中文進行編碼,不然返回給前端的資料中如果有中文的話會被編碼成unicode型別的資料,導致前端看不到中文

  urls.py內容如下:

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    #url(r'^admin/', admin.site.urls),
    url(r'^courses/', views.CourseView.as_view(),name='courses'), #介面就寫好啦
]

  然後啟動專案,在瀏覽器中一訪問,就看到了我們後端返回的json資料:

  

    有人就又說了,我們這麼寫也ok啊,要drf幹嘛,上面這個例子是個簡單的例子,資料簡單、邏輯簡單,你這樣寫當然看著沒有問題啦,但是資料量很大,結構很複雜的時候,你這樣寫的時候就頭疼了。

  所以上面這個例子你就作為了解吧,我們玩一下drf。

玩DRF之前,我們先說一下我們DRF中有哪些內容:

 咱們玩下面10個元件:  a.APIView   (*****)
  b.序列化元件 (*****)
  c.試圖類(mixin) (*****)
  d.認證元件 (*****)
  e.許可權元件
  f.頻率元件
  g.分頁元件
  h.解析器元件 (*****)
  i.相應其元件
  j.url控制器

2.基於DRF來寫介面

  2.1 APIView元件

    在我們的檢視中,通過CBV來寫檢視的時候,繼承APIView,url不變,還是上面那個,通過瀏覽器訪問,照樣能夠看到我們返回的資料,

    views.py內容如下:

from django.shortcuts import render,HttpResponse,redirect
import json
from django.views import View
from app01 import models
#引入APIView,APIView是繼承的django的View,也就是APIView在View的基礎上添加了一些其他的功能
from rest_framework.views import APIView

class CourseView(APIView):
    def get(self,request):
        course_obj_list = models.Course.objects.all()
        ret = []
        for course_obj in course_obj_list:
            ret.append({
                "title":course_obj.title,
                "desc":course_obj.desc,
            })
        return HttpResponse(json.dumps(ret, ensure_ascii=False))

      urls.py內容如下:

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^courses/', views.CourseView.as_view(),name='courses'),
]

      頁面訪問url效果:

      

      照樣拿到了資料,那麼怎麼回事兒呢,我們看原始碼,知道一下APIView的流程就行。

    2.2 解析器元件

      知識準備,還記得一個叫做contentType的http請求頭的東西嗎?回想一下。

      

      後端根據contentType的型別來找到對應的解析資料的方法來解析資料,提取資料

      

      但是django沒有內建的自動解開json資料型別的方法,那麼只能去request.body裡面拿原始的bytes型別的資料,然後自己解,其實很簡單,但是django沒有,可能是早先沒有考慮到。

      

      django自動通過contentType來解析資料的那些方法就叫做django的解析器,能解的是urlencode和檔案的那個mutipart/form-data型別的資料,然後將資料放到了request.POST方法裡面。

    def post(self,request):
        print(request.POST)
        print(type(request)) #通過這個物件的型別(類物件),找到它的原始碼看看
        return HttpResponse('POST')

      而DRF通過自己的解析器,幫我們給request裡面封裝了一個request.data屬性,獲取請求體裡面的資料,然後解析,並且這個解析器基本上能夠解析所有的資料型別,包括django不能自動解析的json資料型別,我們通過Postman(關於Postman工具的使用,看下面那個章節)來除錯一下,看看效果

      

    def post(self,request):
        print(request.data)  #列印結果是:{'name': 'chao'}
        return HttpResponse('POST')

    我們接著往下看:首先我們給我們的試圖類新增一個類變數,這些類變數是用來控制我們檢視類裡面的各個元件

      

    看一下程式碼: 

from django.shortcuts import render,HttpResponse,redirect
import json
from django.views import View
from app01 import models
from rest_framework.views import APIView

#匯入解析器
from rest_framework.parsers import JSONParser,FormParser,MulTiPartParser
# JSONParser:解析json資料的額
# FormParser:解析urlencoded資料的
# FileUploadParser:解析檔案資料的

class CourseView(APIView):
    #寫一個類屬性,名字必須是parser_classes
    parser_classes = [JSONParser,] #裡面存放我們上面匯入的那幾個解析器,如果我們裡面寫了一個JSONParser,那麼解析器只能解析前端傳送過來的json資料,存放到request.data裡面,可以通過postman測試一下看看效果,為什麼?看原始碼吧

    def get(self,request):
        course_obj_list = models.Course.objects.all()
        ret = []
        for course_obj in course_obj_list:
            ret.append({
                "title":course_obj.title,
                "desc":course_obj.desc,
            })
        return HttpResponse(json.dumps(ret, ensure_ascii=False))

    def post(self,request):        print('ok') #你會發現,即便是傳送的資料型別不對,post方法也走了,但是request.data沒有東西,那麼肯定是它出了問題
        print(request.data)  #request.data對我們的資料進行解析的,那麼說明data不是一個變數,而是一個屬性方法,還記得屬性方法嗎
        return HttpResponse('POST')

  原始碼看著比較複雜,這裡我就不列舉了,反正你要知道的是,我們的解析器的查詢使用順序是:

    自己寫的類裡面的parser_classes = [JSONParser,]---->然後找settings中的----->然後找預設的,只要找到,就用了。其他的元件也都是這麼個順序,所以其他的咱們就不看了。

四 Postman的使用

Postman是一個模擬傳送請求並獲得響應結果的工具,不用這個工具的時候,我們寫web專案,除錯介面返回資料的時候,是不是都要啟動專案,通過瀏覽器訪問,然後檢視資料啊,有了這個工具我們就可以不用啟動瀏覽器來,通過這個工具就能進行除錯,首先下載安裝

下載地址:https://www.getpostman.com/downloads/

安裝,然後使用,直接看圖吧,一看就明白:

   

相關推薦

18.DjangoRestFramework學習restful規範APIview解析元件Postman

一 預備知識   預備知識:django的CBV和FBV     CBV(class based view):多用,簡單回顧一下     FBV(function based view):   CBV模式的簡單操作:來個登陸頁面吧   login.html檔案內容如下: <!DOCTYPE html&g

tiny4412學習()從零搭建linux系統(燒寫uboot核心進emmc+uboot啟動核心)

硬體平臺:tiny4412系統:linux-3.5-20151029檔案系統:busybox-1.22.1.tar.bz2編譯器: arm-linux-gcc-4.5.1 目的: 使用uboot引導linux系統,並掛接根檔案系統,搭建起linux開發環境。 由於友

19.DjangoRestFramework學習序列化元件檢視元件

一 序列化元件   首先按照restful規範咱們建立一些api介面,按照下面這些形式寫吧:     Courses --- GET ---> 檢視資料----->返回所有資料列表[{},{},]     Courses--- POST --->新增資料 -----> 返回新增的資料{

20.DjangoRestFramework學習認證元件許可權元件頻率元件url註冊響應分頁元件

一 認證元件   1. 區域性認證元件     我們知道,我們不管路由怎麼寫的,對應的檢視類怎麼寫的,都會走到dispatch方法,進行分發,     在咱們看的APIView類中的dispatch方法的原始碼中,有個self.initial(request, *args, **kwargs),那麼認證、許可

Metasploit框架的學習目錄結構

首先是介紹整個框架的結構: 0x01:最重要的目錄是data,modules,scripts,tools,plugins 1:我們先進去data目錄,該目錄包含大量有用的模組,如meterpreter,exploits,wordlists,templates等等 我們重點注意met

LinuxC基礎學習各類軟體環境介紹

LinuxC基礎學習一之各類軟體環境介紹 一、常用軟體 1、VM12+Ubuntu14.04 2、Everything: 本地搜尋工具 3、Mindmanager:思維導圖工具 4、Xshell:

Android O 學習()HAL型別

備註:這裡已Camera模組為例,如問題,歡迎討論。   以往的hal和framwork的程式碼緊密聯絡起來的,為此google為了framework 升級的方便在Android 8.0 上對 Android 作業系統底層進行了重新架構。新的架構已經瞭解一部分,但仍需要不斷學習,加上

【docker學習】CentOS7.5+Docker安裝及使用「安裝檢視pull建立進入映象」

記錄安裝配置以及使用的過程,可能會有多處摘抄,已註明照抄地址,侵刪。   是什麼:個人理解,是一種移植性很強的虛擬機器,支援版本控制(類似於git),同一個伺服器可以執行多個docker容器,每個docker容器都有一個獨立的虛擬環境。 本人環境: 虛擬機器:Oracle

sklearn 學習實踐——基於自帶資料集(波士頓房價鳶尾花糖尿病)構建分類迴歸模型

      只要是接觸機器學習的,很少有沒聽過sklearn的,這個真的可以稱得上是機器學習快速進行的神器了,在研究生的時候搭建常用的機器學習模型用的就是sklearn,今天應部門的一些需求,簡單的總結了一點使用方法,後面還會繼續更新,今天僅使用sklearn自帶的資料

JavaScript專題學習 JavaScript簡單介紹

JavaScript介紹            行業內簡稱為js,後面還有一個jquery是javaScript的封裝框架非常重要,所以這兩個請一定要掌握!!!在實際專案工作中,必須會用到這兩個,所以覺得這兩個比較弱的,還是有必要再好好練習下!!! 如果對您有幫助 ,請

學習DockerDocker初體驗---SpringBoot整合Docker的部署釋出與應用

準備工作 會一點springboot 不會沒關係,花十幾分鍾補一下Quick-SpringBoot 會一點Maven 不會沒關係,花幾分鐘補一下Maven的快速應用 會一點Linux命令 不會沒關係,花十幾分再補一下Linux菜鳥教程 一臺

Spring Boot學習Spring Beans和依賴注入

  你可以自由地使用任何標準的Spring框架技術去定義beans和它們注入的依賴。簡單起見,我們經常使用 @ComponentScan 註解搜尋beans,並結合 @Autowired 構造器注入。   如果遵循以上的建議組織程式碼結構(將應用的main類放到包的最上層,即rootpackage),那麼你

Spring Boot學習配置類及自動配置

一、配置類 1. 匯入其他配置類  你不需要將所有的 @Configuration 放進一個單獨的類, @Import 註解可以用來匯入其他配置類。另外,你也可以使用 @ComponentScan 註解自動收集所有Spring元件,包括 @Configuration 類。 2. 匯入XML配置  如果必

Android Binder學習()Binder中的資料結構

 備註:雙向箭頭表示雙向連結串列,各成員是串聯起來的。    在分析Android framework程式碼時,遇到最多的就是binder程序間通訊了。如果只知道怎麼用,也不影響我們日常的工作。但如果你想閱讀binder原始碼,就需要花點時間了。相對與linux核心來說,A

Android 動畫學習()View Animation

Android動畫初步         動畫(Animation)在我們日常的Android開發工作當中使用得較為頻繁,尤其對於Android遊戲這個動畫的集合體,掌握動畫開發的重要性毋庸置疑。同

Python3.x學習 HelloWorld!

這是博主第一次寫部落格,以前也一直想寫點什麼,但是一來沒有時間,二來也沒什麼東西可寫點,這次趁著學習Python3.x的機會,寫寫部落格與大家共勉。 Python是一門非常強大的指令碼語言,應用場景十分廣泛,不僅可以寫web網站,而且可以為各個領域的各個環節的工作提供幫助,

canvas學習canvas的基本使用

一、canvas 1.canvas是html5中的一個標籤,通過canvas的getContext得到上下文可以繪圖等操作。canvas通過js進行API操作,可以得到想要的圖形或動畫。 2.html5中canvas有兩套尺寸,第一個是元素本身的大小,在標籤

QT學習畫板製作(解決繪畫卡頓)

    hello,大家好。    本人學習了一段時間的Qt,今天在公司電視大屏有個畫板工具功能,靈機一動製作一個簡易的畫板程式。    本文主要介紹如何採用QWidget,QPainter製作畫板。    畫板功能:全屏無邊框畫板,支援手繪,右鍵(偷懶= -0- =)擦除。

Vue學習筆記vue-cli專案搭建及解析

Vue (一)安裝node.js 首先需要安裝node環境,可以直接到中文官網http://nodejs.cn/下載安裝包。 只是這樣安裝的 node 是固定版本的,如果需要多版本的 node,可以使用 nvm 安裝http://blog.csdn.net/s8460049/art

Lucene學習總結七:Lucene搜尋過程解析

2.4、搜尋查詢物件 2.4.4、收集文件結果集合及計算打分 在函式IndexSearcher.search(Weight, Filter, int) 中,有如下程式碼: TopScoreDocCollector collector = TopScoreDocCollector.create