CVB:基於類的視圖函數,resful規範,序列化

1 CBV的源碼分析
-Class Base View(基於類的視圖)
-Function Base View(基於函數的視圖)
-def as_view 類方法
-def view:類方法內部,閉包函數定義:內層函數包含對外部作用域的引用
-python中一切皆對象:函數也是對象
-hasattr(self, 'get')--判斷self類中是不是有該(get)方法
-反射 setattr(self,get,get_all):相當於把get函數,變成了get_all
-getattr(self, 'get'):拿到get函數的內存地址

  • def view(request, args, kwargs):
    self = cls(
    initkwargs)
    if hasattr(self, 'get') and not hasattr(self, 'head'):
    self.head = self.get
    self.request = request
    self.args = args
    self.kwargs = kwargs
    #執行:dispatch:誰的dispatch方法?寫的cbv的那個c,視圖中的那個視圖類
    #我這個類如果沒有寫dispatch,會執行View中的dispatch方法
    return self.dispatch(request,
    args, kwargs)
    -def dispatch(self, request, *args, *kwargs):
    #request.method 前臺請求的方法,轉成了小寫
    #http_method_names View中定義的一個列表:是一堆請求方式
    if request.method.lower() in self.http_method_names:
    #getattr的第三個參數是默認值:self.http_method_not_allowed
    #拿到get方法的內存地址
    handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
    handler = self.http_method_not_allowed
    #get(request,
    args,
    kwargs)
    return handler(request, *args, **kwargs)

-總結:
-路由配置好,項目啓動:as_view()---->返回結果是一個函數的內存地址
-請求來了---->觸發函數的執行,就會執行dispatch方法---->根據請求的不同,分發到不同的視圖函數

1.1 閱讀源碼:
左側工程欄--->設置圖標-->點擊--->show members(能看到py文件,類的方法)

2 resful規範(是什麼)
-什麼是resful(定義)
-是一個規範
-面向資源編程:把網絡中所有東西,想象成資源
-規範:
-10條規範
-API與用戶的通信協議,總是使用HTTPs協議:https比http安全
-域名
https://api.example.com 儘量將API部署在專用域名(會存在跨域問題)
https://example.org/api/ API很簡單
例如寫一個查詢所有圖書的api接口:https://api.example.com/books
https://127.0.0.1/api/books
-版本:每個接口都應該有版本
URL,如:https://api.example.com/v1/ https://127.0.0.1/api/v2/books(推薦用這種)
請求頭 跨域時,引發發送多次請求
-路徑,視網絡上任何東西都是資源,均使用名詞表示(可複數)
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
同一都用這個:
https://api.example.com/v1/books
-method
GET :從服務器取出資源(一項或多項)
POST :在服務器新建一個資源
PUT :在服務器更新資源(客戶端提供改變後的完整資源)
PATCH :在服務器更新資源(客戶端提供改變的屬性)
DELETE :從服務器刪除資源
-過濾,通過在url上傳參的形式傳遞搜索條件
https://api.example.com/v1/zoos?limit=10:指定返回記錄的數量
-狀態碼
請求回去,需要有狀態碼
自定義狀態碼
status: 100表示成功
101表示用戶名密碼錯誤
102我也不知道什麼錯誤
-錯誤處理,應返回錯誤信息,error當做key。
-{status:100,error:'錯誤信息寫上'}
-返回結果,針對不同操作,服務器向用戶返回的結果應該符合以下規範。
GET /books:返回資源對象的列表(數組)
GET /books/1:返回單個資源對象
POST /books:返回新生成的資源對象 -新增,傳數據,一旦新增完成,把新的資源對象返回
PUT /books/1:返回完整的資源對象
PATCH /books/1:返回完整的資源對象
DELETE /books/1:返回一個空文檔
-Hypermedia API,RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API 方法,使得用戶不查文檔,也知道下一步應該做什麼。
{
status:100
msg:成功
url:127.0.0.1/books/1
}
核心:返回結果中提供鏈接

2.1 django寫resful規範的接口
2.2 postman軟件:模擬發請求的軟件
2.3 格式化json格式數據
-https://www.json.cn/
2.4 put請求,django不會幫我解析body內的數據,需要自己處理

3 drf(django rest framework)框架(django的app)
安裝:djangorestframework
-它是一個app,要在咱的項目中用
-只是快速的構建resful規範的接口
-csrf_exempt:局部禁用csrf(csrf是可以局部使用,局部禁用)
-以後再執行的dispatch方法是APIView的dispatch方法

    APIView 類
    -繼承了View
    -重寫了as_view方法,在內部屏蔽了xsrf
    -重寫了dispatch方法---核心

        Request 類
    -封裝了原來的request
    -request.data   --->前臺傳遞過來的數據,放在裏面
    -request重寫了__getattr__方法
    -request.query_params   就是原來request.的GET

-getattr和setattr
-重點掌握這三點:
    -request.data 是個方法,包裝成了屬性,前臺傳過來body體中數據的數據,放在裏面
    -request.query_params  這個是原來GET中的數據
    -request把原來的request包裝進去了

4 APIView源碼分析

5 序列化
-1 自己寫for循環來處理(麻煩)
-2 django提供的序列化組件(不可控)
from django.core import serializers
ret=serializers.serialize('json','queryset對象')
ret就是序列化之後的字符串了,不需要再序列化了
-3 drf給咱提供的序列化組件
-1 先導入
from rest_framework.serializers import Serializer
from rest_framework import serializers
-2 寫一個類,繼承Serializer
-3 在類內部寫屬性:
name=serializers.CharField()
-4 使用:
-先生成對象,需要傳參數 instance:要序列化的對象(可能是queryset,也可能是單個對象)
many:如果是queryset---True,,如果是單個對象--False
-5 對象.data --->是一個字典

-1 重命名:用source:xx = serializers.CharField(source='name')
-2 取出出版社名字:
方式一:
-在模型表中重寫str方法
-publish=serializers.CharField()
方式二:
-用source
-拿出出版社的城市
-publish=serializers.CharField(source='publish.city')

            *****如果不指定source,字段必須對應起來,如果指定了source,字段可以任意命名
        -source 可以指定字段,也可也指定方法
            publish.test這是個方法,會執行該方法,並拿到返回結果
            test = serializers.CharField(source='publish.test')
        -3 SerializerMethodField,可以指定一個方法
            publish=serializers.SerializerMethodField()

# 方法名:叫get_字段名,要傳參數,參數是:當前book對象
def get_publish(self,obj):

obj 是當前book對象

                dic={'name':obj.publish.name,'email':obj.publish.email}
                return dic
            -方法內部可以繼續用其他的序列化類
    -ModelSerializer
        -必須在類中寫
        class Meta:
            model=指定表
    **      # fields = 'all'**
            # 指定只取這兩個字段
            fields = ['nid','name']

** # 去掉指定的字段

exclude=['publish','authors']**

    **      # fields,跟exclude不能連用
            # 指定深度,就是跨幾個表(官方建議小於10,我給你的建議小於3)
            # depth = 2**

作業:
1 什麼是冪等性 (put請求是冪等的,post請求不是冪等的)
2 圖書的其他resful的接口寫完(用drf的序列化組件)
3 講的整理出來
-resful的規範
-APIView的執行流程
-Request對象
-序列化組件(不用着急)

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