Django - DRF - RESTful規範,及Django實現

目錄

一、RESTful概念 - 一種開發規範

二、 RESTful - 10條規範

2-1 API與用戶的通信協議,總是使用HTTPs協議

2-2 API部署的兩種規範

2-2-1 方式一、將API部署在本站域名內部 - 不推薦,存在跨域問題

2-2-2 方式二、將API部署在域名末尾 - 推薦,使用簡單

2-3 API在路徑上的書寫原則 - 面向資源

2-4 API的版本部署規則(兩種方式)

2-4-1 方式一、部署在url上(兩種方式)

2-4-2 方式二、放在請求頭內(不推薦,跨域時會引發多次請求)

2-5 RESTful規範支持方法

2-5-1 冪等性 - 對接口的多次調用所產生的結果和調用一次是一致的

2-6 過濾方式規範 - 通過在url上傳參的形式傳遞搜索條件

2-7 使用狀態碼錶達結果狀態

2-8 錯誤信息的返回 - key-value形式

2-9 不同路由方法申請,對相同路由的不同結果返回

2-10 Hypermedia API - 返回結果中提供指向其他API的鏈接

三、Django實現RESTful規範操作

3-1 基於FBV的實現方式

3-2 基於CBV的實現方式

3-3 基於CBV對RESTful規範方法的實現 

3-3-1 使用Postman 跳過前端模擬請求獲取數據

3-3-2 使用Postman的報錯信息總結


一、RESTful概念 - 一種開發規範

  • REST(Representational State Transfer 表徵狀態轉移)與技術無關,代表的是一種軟件架構風格
  • REST從資源的角度類審視整個網絡,它將分佈在網絡中某個節點的資源通過URL進行標識,客戶端應用通過URL來獲取資源的表徵,獲得這些表徵致使這些應用轉變狀態
  • 所有的數據,不過是通過網絡獲取的還是操作(增刪改查)的數據,都是資源,將一切數據視爲資源是REST區別與其他架構風格的最本質屬性
  • 對於REST這種面向資源的架構風格,有人提出一種全新的結構理念,即:面向資源架構(ROA:Resource Oriented Architecture)

二、 RESTful - 10條規範

自主學習查詢

自主學習查詢 - 二

2-1 API與用戶的通信協議,總是使用HTTPs協議

HTTPs = HTTP + SSL ,部署需要去域名站點申請SSL證書

SSL/TLS協議運行機制的概述

2-2 API部署的兩種規範

2-2-1 方式一、將API部署在本站域名內部 - 不推薦,存在跨域問題

# https://api.example.com
例如寫一個查詢所有圖書的api接口 - https://api.example.com/books

2-2-2 方式二、將API部署在域名末尾 - 推薦,使用簡單

# https://example.org/api/
例如寫一個查詢所有圖書的api接口:https://127.0.0.1/api/books

2-3 API在路徑上的書寫原則 - 面向資源

'''視網絡上任何東西都是資源,均使用名詞表示(可複數)'''

# 例如:
https://api.example.com/v1/books
https://api.example.com/v1/animals
https://api.example.com/v1/employees

# 不能這麼寫:
-獲取所有圖書:https://127.0.0.1/api/get_all_books
-新增一本書:https://127.0.0.1/api/add_book

# 統一都books名詞:
https://api.example.com/v1/books

2-4 API的版本部署規則(兩種方式)

2-4-1 方式一、部署在url上(兩種方式)

# 方式一
https://api.example.com/v1/books
# 方式二(推薦)
https://example.org/api/v1/books

2-4-2 方式二、放在請求頭內(不推薦,跨域時會引發多次請求)

2-5 RESTful規範支持方法

GET 從服務器取出資源(一項或多項)
POST 在服務器新建一個資源 - 非冪等
PUT 在服務器更新資源(客戶端提供改變後的完整資源,即獲取對象所在的所有資源內容) - 冪等
PATCH 在服務器更新資源(客戶端提供改變的屬性,即只獲取改變的對象) 
DELETE 從服務器刪除資源

2-5-1 冪等性 - 對接口的多次調用所產生的結果和調用一次是一致的

例:put請求是冪等的,post請求不是冪等的

 

2-6 過濾方式規範 - 通過在url上傳參的形式傳遞搜索條件

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

2-7 使用狀態碼錶達結果狀態

詳細狀態碼查詢API

200 OK - [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
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 - [*]:服務器發生錯誤,用戶將無法判斷髮出的請求是否成功。

2-8 錯誤信息的返回 - key-value形式

{status:100,error:'錯誤信息'}

2-9 不同路由方法申請,對相同路由的不同結果返回

GET /books:返回資源對象的列表(數組)
GET /books/1:返回單個資源對象

POST /books:新建資源對象,返回新生成的資源對象
PUT /books/1:更新單個對象資源,返回完整的資源對象
PATCH /books/1:更新單個對象資源,返回完整的資源對象
DELETE /books/1:刪除單個對象資源,返回一個空文檔

2-10 Hypermedia API - 返回結果中提供指向其他API的鏈接

{
status:100
msg:成功
url:127.0.0.1/books/1
}

三、Django實現RESTful規範操作

注意:

  • Django存在侷限性,只封裝了POST和GET方法,對於其他方法需要自行封裝操作(對body進行處理)

3-1 基於FBV的實現方式

def user(request):

    if request.method=='GET':
        dic = {'status':200,'name': 'name', 'age': 18}
        return HttpResponse(json.dumps(dic))

    elif request.method=='POST':
        # 狀態碼的返回,及信息返回
        dic = {'status': 200, 'msg': '修改成功','url':'127.0.0.1/users/1'}
        return JsonResponse(dic)

3-2 基於CBV的實現方式

from django.shortcuts import render, HttpResponse
from django.views import View

class Test(View):
    # dispatch用於請求的分發,若重寫則覆蓋,必須調用父類的原生方法
    def dispatch(self, request, *args, **kwargs):
        print(11)
        return super().dispatch(request, *args, **kwargs)

    # 如果發送一個get 請求,會響應到這個函數
    # request必須傳,後面的可傳可不傳(有可能有名,無名分組)
    def get(self, request, *args, **kwargs):
        print('get')
        return render(request, 'login.html')

    def post(self, request):
        name = request.POST.get('name')
        pwd = request.POST.get('pwd')
        if name == 'lqz' and pwd == '123':
            return HttpResponse('登錄成功')
        else:
            return render(request, 'login.html', {'error': '用戶名或密碼錯誤'})

3-3 基於CBV對RESTful規範方法的實現 

'''
路由設計
    url(r'^books/$', views.Books.as_view()),
    url(r'^books/(?P<pk>\d+)', views.Books.as_view()),
'''

from app01 import models

# 基於CBV模擬resful規範的接口 - get、put、post
class Books(View):
    # 獲取所有圖書
    def get(self, request):
        print(type(request))
        response = {'status': 100, 'data': None}
        books = models.Book.objects.all()
        # 先構造出所有書籍的字典的列表
        ll = [{'name': book.name, 'price': book.price} for book in books]
        # 返回數據是json格式數據
        response['data'] = ll
        return JsonResponse(response, safe=False)

    # 數據的修改 - Django內部未支持,自主對傳輸的數據進行反序列化處理
    def put(self, request, pk):
        import json
        data=json.loads(str(request.body,encoding='utf-8'))
        name=data.get('name')
        price=data.get('price')
        ret = models.Book.objects.filter(pk=pk).update(name=name,price=price)
        print(ret)
        return JsonResponse({'status': 100, 'msg': '修改成功'})

    # 數據的查詢
    def post(self, request, pk):
        print(pk)
        print(request.method)
        print(request.body)
        print(request.POST)
        print(request.GET)
        name = request.POST.get('name')
        price = request.POST.get('price')
        print(name)
        ret = models.Book.objects.filter(pk=pk).update(name=name,price=price)
        print(ret)
        return JsonResponse({'status': 100, 'msg': '修改成功'})

3-3-1 使用Postman 跳過前端模擬請求獲取數據

 

 

 

3-3-2 使用Postman的報錯信息總結

解決方式:使用Django的後臺傳輸,不支持CSRF傳輸,需要註釋(不安全)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章