1. 程式人生 > >django的rest framework框架——01

django的rest framework框架——01

一、django的FBV 和 CBV

1、FBV(基於函式的檢視):

urlpatterns = [
    url(r'^users/', views.users),
]
def users(request):
    user_list = ["amy", "jack", "lily"]
    return HttpResponse(json.dumps(user_list))

2、CBV(基於類的檢視):

urlpatterns = [
    url(r'^students/', views.StudentsView.as_view()),
]
from django.views import View
class
StudentsView(View): def get(self, request, *args, **kwargs): """get方法訪問""" return HttpResponse("get") def post(self, request, *args, **kwargs): """post方法訪問""" return HttpResponse("post") def put(self, request, *args, **kwargs):
"""put方法訪問""" return HttpResponse("put") def delete(self, request, *args, **kwargs): """delete方法訪問""" return HttpResponse("delete")

3、CBV實現原理

dispatch()方法的實現相當於:

from django.views import View


class StudentsView(View):
    def dispatch(self, request, *args, **kwargs):
        func 
= getattr(self, request.method.lower()) # 通過反射獲取請求方法(記得把獲取到的方法名變成小寫) return func(request, *args, **kwargs) # 執行這個方法並將結果返回給使用者

CBV就是通過路由,執行view()方法,再通過dispatch()方法基於反射,根據不同的請求方式來執行這些請求方法,如get、post、patch等。

若是繼承父類的dispatch方法:

class StudentsView(View):
    def dispatch(self, request, *args, **kwargs):
        # 繼承父類的dispatch方法
        return super(StudentsView, self).dispatch(request, *args, **kwargs)

 4、多個類繼承基類

多個類公用的功能可以用繼承來實現:

from django.views import View


class MyBaseView(object):
    def dispatch(self, request, *args, **kwargs):
        # 繼承父類的dispatch方法
        return super(MyBaseView, self).dispatch(request, *args, **kwargs)


class StudentsView(MyBaseView, View):

    def get(self, request, *args, **kwargs):
        """get方法訪問"""
        return HttpResponse("get")

    def post(self, request, *args, **kwargs):
        """post方法訪問"""
        return HttpResponse("post")

    def put(self, request, *args, **kwargs):
        """put方法訪問"""
        return HttpResponse("put")

    def delete(self, request, *args, **kwargs):
        """delete方法訪問"""
        return HttpResponse("delete")


class TeachersView(MyBaseView, View):

    def get(self, request, *args, **kwargs):
        """get方法訪問"""
        return HttpResponse("get")

    def post(self, request, *args, **kwargs):
        """post方法訪問"""
        return HttpResponse("post")

    def put(self, request, *args, **kwargs):
        """put方法訪問"""
        return HttpResponse("put")

    def delete(self, request, *args, **kwargs):
        """delete方法訪問"""
        return HttpResponse("delete")
View Code

5、CBV的csrf認證

方法1:給dispatch()方法加上裝飾器,即可讓該檢視免於csrftoken認證:

import json
from django.shortcuts import render, HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator


class StudentsView(View):

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(StudentsView, self).dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        """get方法訪問"""
        return HttpResponse("get")

    def post(self, request, *args, **kwargs):
        """post方法訪問"""
        return HttpResponse("post")

    def put(self, request, *args, **kwargs):
        """put方法訪問"""
        return HttpResponse("put")

    def delete(self, request, *args, **kwargs):
        """delete方法訪問"""
        return HttpResponse("delete")
View Code

方法2:給類加上裝飾器,使得該檢視免於csrftoken認證:

from django.shortcuts import render, HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator


@method_decorator(csrf_exempt, name="dispatch")
class StudentsView(View):

    def get(self, request, *args, **kwargs):
        """get方法訪問"""
        return HttpResponse("get")

    def post(self, request, *args, **kwargs):
        """post方法訪問"""
        return HttpResponse("post")

    def put(self, request, *args, **kwargs):
        """put方法訪問"""
        return HttpResponse("put")

    def delete(self, request, *args, **kwargs):
        """delete方法訪問"""
        return HttpResponse("delete")
View Code

 

二、基於Django實現restful api

1、例:訂單的增刪改查

對於普通的藉口開發:

from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^get_order/', views.get_order),
    url(r'^del_order/', views.del_order),
    url(r'^add_order/', views.add_order),
    url(r'^update_order/', views.update_order),
]
View Code
from django.shortcuts import render, HttpResponse


def get_order(request):
    return HttpResponse("get_order")


def del_order(request):
    return HttpResponse("del_order")


def update_order(request):
    return HttpResponse("update_order")


def add_order(request):
    return HttpResponse("add_order")
View Code

這種方式在url比較多的情況下並不實用,所以我們引出了restful規範,根據請求方式的不同來進行不同的操作:

  get請求→查詢

  post請求→建立

  delete請求→刪除

  put請求→更新

(1)基於FBV的寫法:

from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^order/', views.order),
]
View Code
from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt


@csrf_exempt
def order(request):
    if request.method == "GET":
        return HttpResponse("查詢訂單")
    elif request.method == "POST":
        return HttpResponse("建立訂單")
    elif request.method == "DELETE":
        return HttpResponse("刪除訂單")
    elif request.method == "PUT":
        return HttpResponse("更新訂單")
View Code

(2)基於CBV的寫法:

from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^order/', views.OrderView.as_view()),
]
View Code
from django.shortcuts import render, HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator


@method_decorator(csrf_exempt, name="dispatch")
class OrderView(View):
    def get(self, request, *args, **kwargs):
        return HttpResponse("查詢訂單")

    def post(self, request, *args, **kwargs):
        return HttpResponse("建立訂單")

    def delete(self, request, *args, **kwargs):
        return HttpResponse("刪除訂單")

    def put(self, request, *args, **kwargs):
        return HttpResponse("更新訂單")
View Code

 

三、RESTful協議

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

1、API與使用者的通訊協議,總是使用https協議

2、域名

  • 子域名的方式(存在跨域問題)
www.baidu.com  # 使用者訪問這個
api.baidu,com  # 返回json資料
  • URL方式
www.baidu.com  # 使用者訪問這個
www.baidu,com/aip/  # 返回json資料

3、版本

  • 加到URL上:https://www.baidu.com/api/v1/
  • 加到請求頭上(跨域時,會引發多次請求)

4、路徑

將網路上的一切東西都看作資源,都使用名詞表示(也可以用複數):

  https://www.baidu.com/api/v1/user/

  https://www.baidu.com/api/v1/users/

5、method

  • GET   從伺服器取出資源(一項或多項)
  • POST  在伺服器新建一個資源
  • PUT    在伺服器更新資源(客戶端提供改變後的完整資源,全部更新)
  • PATCH  在伺服器更新資源(客戶端提供改變後的屬性,區域性更新)
  • DELETE  從伺服器刪除資源

6、過濾

https://www.baidu.com/api/v1/user/?status=1&page=2  # 表示status=1的、第2頁的使用者

7、狀態碼

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 - [*]:伺服器發生錯誤,使用者將無法判斷髮出的請求是否成功。

更多看這裡:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
常見狀態碼

例:

8、錯誤處理

狀態碼為4xx時,應返回錯誤資訊:

{
    error: "Invalid API key"
}

9、返回結果

根據不同的操作,返回不同的結果:

GET /order/:返回所有訂單列表(陣列)
GET /order/1/:返回單個訂單的詳細資訊(資源物件)
POST /order/:返回新生成的訂單
PUT /order/1/:返回修改後完整的訂單資訊
PATCH /order/1/:返回修改後的訂單資訊(區域性)
DELETE /oder/1/:刪除訂單  返回一個空文件
常用規範示例

10、Hypermedia API 

在返回結果中提供連結,連向其他API方法,使得使用者不用查文件,通過這個連結來獲取資料

 四、Django rest framework框架

1、安裝

pip3 install djangorestframework

2、Django rest framework認證原始碼及實現

rest_framework的dispatch方法:

如何獲取加工後的request的值:

到這個加工過的Request裡面去看看user都幹了些什麼:

實現認證:

可以自定製認證類:

from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^course/', views.CourseView.as_view()),
]
urls.py
from django.shortcuts import render, HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from rest_framework.views import APIView
from rest_framework.authentication import BasicAuthentication
from rest_framework import exceptions


class MyAuthentication(object):
    """自定製認證"""

    def authenticate(self, request):
        # 去請求裡面獲取資訊,到資料庫中進行校驗,如果校驗失敗就丟擲異常
        token = request._request.GET.get("token")
        if not token:
            raise exceptions.AuthenticationFailed("使用者認證失敗")
        return ("amy", None)

    def authenticate_header(self, val):
        pass


@method_decorator(csrf_exempt, name="dispatch")
class CourseView(APIView):
    authentication_classes = [MyAuthentication]  # 使用自定義的 authentication_classes

    def get(self, request, *args, **kwargs):
        print(request.user)  # 列印 amy
        return HttpResponse("查詢課程")

    def post(self, request, *args, **kwargs):
        return HttpResponse("建立課程")

    def delete(self, request, *args, **kwargs):
        return HttpResponse("刪除課程")

    def put(self, request, *args, **kwargs):
        return HttpResponse("更新課程")
views.py