Django restframwork

REST介紹

全稱Representational State Transfer,即表現層狀態轉換,若是一個架構符合REST原則,咱們就稱他爲Restfull架構,其主要包括以下方面:html

  • 資源Resources

REST的名稱"表現層狀態轉化"中,省略了主語。"表現層"其實指的是"資源"(Resources)的"表現層"。shell

所謂"資源",就是網絡上的一個實體,或者說是網絡上的一個具體信息。它能夠是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的實在。你能夠用一個URI(統一資源定位符)指向它,每種資源對應一個特定的URI。要獲取這個資源,訪問它的URI就能夠,所以URI就成了每個資源的地址或獨一無二的識別符。django

所謂"上網",就是與互聯網上一系列的"資源"互動,調用它的URI。json

  • 表現層 Representation

"資源"是一種信息實體,它能夠有多種外在表現形式,咱們把"資源"具體呈現出來的形式,叫作它的」表現「api

好比,文本能夠用txt格式表現,也能夠用HTML格式、XML格式、JSON格式表現,甚至能夠採用二進制格式;圖片能夠用JPG格式表現,也能夠用PNG格式表現。服務器

URI只表明資源的實體,不表明它的形式。嚴格地說,有些網址最後的".html"後綴名是沒必要要的,由於這個後綴名錶示格式,屬於"表現層"範疇,而URI應該只表明"資源"的位置。它的具體表現形式,應該在HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個字段纔是對"表現層"的描述restful

  • 狀態轉化(State Transfer)網絡

    訪問一個網站,就表明了客戶端和服務器的一個互動過程。在這個過程當中,勢必涉及到數據和狀態的變化。架構

    互聯網通訊協議HTTP協議,是一個無狀態協議。這意味着,全部的狀態都保存在服務器端。所以,若是客戶端想要操做服務器,必須經過某種手段,讓服務器端發生"狀態轉化"(State Transfer)。而這種轉化是創建在表現層之上的,因此就是"表現層狀態轉化"。app

    客戶端用到的手段,只能是HTTP協議。具體來講,就是HTTP協議裏面,四個表示操做方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操做:GET用來獲取資源,POST用來新建資源(也能夠用於更新資源),PUT用來更新資源,DELETE用來刪除資源。

    綜上,其實RESTful架構就是:

    ​ (1)每個URI表明一種資源;

      (2)客戶端和服務器之間,傳遞這種資源的某種表現層;

      (3)客戶端經過四個HTTP動詞,對服務器端資源進行操做,實現"表現層狀態轉化"。

    RESTful架構設計規範

    • 但願URI中不出現動詞

      如 顯示文章

      野生寫法:/artical/show/1

      正規寫法:/artical/1

      若是必需要動詞,此時動詞須要看做爲一個服務,如銀行轉帳,從帳戶1向帳戶2匯款500元

      野生寫法:POST /accounts/1/transfer/500/to/2

      正規寫法:

      POST /transaction HTTP/1.1
      
        Host: 127.0.0.1
      
        from=1&to=2&amount=500.00
    • 但願URL中不出現版本號

    http://www.example.com/app/1.0/foo
    
      http://www.example.com/app/1.1/foo
    
      http://www.example.com/app/2.0/foo

    由於不一樣的版本,能夠理解成同一種資源的不一樣表現形式,因此應該採用同一個URI。版本號能夠在HTTP請求頭信息的Accept字段中進行區分

    • 協議 API最好使用https

    • 域名 儘可能使用專用API域名,如 api.baidu.com

    • 路徑 又稱爲endpoint,表示API的具體資源,在restfull架構中,每一個URI表明一種資源,因此URI中的名詞需和實際功能對應

    • HTTP 動詞

      • 經常使用動詞

        GET(select) 獲取資源

        POST (create)建立資源

        PUT (update)更新資源(客戶端提供改變後的完整資源)

        DELETE (delete)刪除資源

        PATCH(update) 更新資源(客戶端提供改變的屬性)

      • 不經常使用的HTTP動詞:

        HEAD 獲取資源的元數據

        OPTIONS 獲取信息,關於資源的那些屬性是客戶端能夠改變的

    • 過濾信息

      若是記錄的數量不少,服務器須要分段返回給用戶,API應該提供參數,過濾返回結果,以下:

      • ?limit=10 指定返回的記錄數量
      • ?offset=10 指定反饋記錄的開始位置
      • ?page=2&per_page=100 指定第幾頁,以及每頁的記錄數量
      • ?sortby=name&order=asc 指定返回的結果按那個屬性進行排序,以及如何排序
      • ?animal_type_id=1 指定篩選條件
    • 狀態碼

      • 200 (「OK」) 用於通常性的成功返回, 不可用於請求錯誤返回
      • 201 (「Created」) 資源被建立
      • 202 (「Accepted」) 用於Controller控制類資源異步處理的返回,僅表示請求已經收到。對於耗時比較久的處理,通常用異步處理來完成
      • 204 (「No Content」) 此狀態可能會出如今PUT、POST、DELETE的請求中,通常表示資源存在,但消息體中不會返回任何資源相關的狀態或信息。
      • 301 (「Moved Permanently」) 資源的URI被轉移,須要使用新的URI訪問
      • 302 (「Found」) 不推薦使用,此代碼在HTTP1.1協議中被303/307替代。咱們目前對302的使用和最初HTTP1.0定義的語意是有出入的,應該只有在GET/HEAD方法下,客戶端才能根據Location執行自動跳轉,而咱們目前的客戶端基本上是不會判斷原請求方法的,無條件的執行臨時重定向
      • 303 (「See Other」) 返回一個資源地址URI的引用,但不強制要求客戶端獲取該地址的狀態(訪問該地址)
      • 304 (「Not Modified」) 有一些相似於204狀態,服務器端的資源與客戶端最近訪問的資源版本一致,並沒有修改,不返回資源消息體。能夠用來下降服務端的壓力
      • 307 (「Temporary Redirect」) 目前URI不能提供當前請求的服務,臨時性重定向到另一個URI。在HTTP1.1中307是用來替代早期HTTP1.0中使用不當的302
      • 400 (「Bad Request」) 用於客戶端通常性錯誤返回, 在其它4xx錯誤之外的錯誤,也可使用400,具體錯誤信息能夠放在body中
      • 401 (「Unauthorized」) 在訪問一個須要驗證的資源時,驗證錯誤
      • 403 (「Forbidden」) 通常用於非驗證性資源訪問被禁止,例如對於某些客戶端只開放部分API的訪問權限,而另一些API可能沒法訪問時,能夠給予403狀態
      • 404 (「Not Found」) 找不到URI對應的資源
      • 405 (「Method Not Allowed」) HTTP的方法不支持,例如某些只讀資源,可能不支持POST/DELETE。但405的響應header中必須聲明該URI所支持的方法
      • 406 (「Not Acceptable」) 客戶端所請求的資源數據格式類型不被支持,例如客戶端請求數據格式爲application/xml,但服務器端只支持application/json
      • 409 (「Conflict」) 資源狀態衝突,例如客戶端嘗試刪除一個非空的Store資源
      • 412 (「Precondition Failed」) 用於有條件的操做不被知足時
      • 415 (「Unsupported Media Type」) 客戶所支持的數據類型,服務端沒法知足
      • 500 (「Internal Server Error」) 服務器端的接口錯誤,此錯誤於客戶端無關
    • 返回結果

      針對不一樣的操做,server向用戶返回的結果應該符合以下規範

      • GET 返回資源對象的列表或單個資源
      • POST 返回新生的資源對象
      • PUT 返回完整的資源對象
      • PATCH 返回完整的資源對象
      • DELETE 返回空文檔,並告知結果

Django + RESTful安裝配置

RESTful api 關於django的插件名爲 djangorestframework,官方網站爲:http://www.django-rest-framework.org/

  • 安裝

pip install djangorestframework

  • setting配置

在project的settings.py中進行註冊app,並添加驗證配置

INSTALLED_APPS = [
   ...
    'rest_framework',
]

#對於匿名只讀
REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ]
}
  • models配置
class IDC(models.Model):
    '''機房'''
    name = models.CharField(max_length=64, unique=True)
    def __str__(self):
        return self.name

class Host(models.Model):
    hostname = models.CharField(max_length=64,unique=True)
    ip_addr = models.GenericIPAddressField()
    port = models.SmallIntegerField(default=22)
    idc = models.ForeignKey('IDC',blank=True,null=True)
    system_type_choices = ((0,'Linux'),(1,'Windows'))
    system_type = models.SmallIntegerField(choices=system_type_choices,default=0)
    memo = models.CharField(max_length=128,blank=True,null=True)
    enabled = models.BooleanField(default=1,verbose_name="啓用本機")

    class Meta:
        unique_together = ('ip_addr','port')
        verbose_name = "主機表"
    def __str__(self):
        return "%s(%s)"%( self.hostname,self.ip_addr)
  • Serializers配置

rest_serializer.py

from app01 import models
from rest_framework import serializers
class IDCSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.IDC
        fields = ('name',)




class HostSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Host
        fields = ('id','hostname','ip_addr','port','idc','system_type','memo','enabled')
  • views配置

rest_views.py

from rest_framework import viewsets
from app01 import models
from app01 import rest_searializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = models.UserProfile.objects.all()
    serializer_class = rest_searializer.UserSerializer

class IDCViewSet(viewsets.ModelViewSet):
    queryset = models.IDC.objects.all()
    serializer_class = rest_searializer.IDCSerializer

class HostViewSet(viewsets.ModelViewSet):
    queryset = models.Host.objects.all()
    serializer_class = rest_searializer.HostSerializer
  • URL 配置
from rest_framework import routers
from app01 import rest_viewset
from django.conf.urls import url,include
router = routers.DefaultRouter()
router.register(r'idc',rest_viewset.IDCViewSet)
router.register(r'host',rest_viewset.HostViewSet)


urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
  • 啓動Django 測試

http://127.0.0.1:8000/api/

後續會對上述的全部點進行詳細說明。

相關文章
相關標籤/搜索