宿舍得

第二夢發表於2019-02-16

1.序列化輸出:

1.定義序列化器欄位的作用
    1.
    2.
    補充:read_only,write_only

2.`JsonResponse({book_dict})`

JsonResponse({“bookinfo”:book_dict_list}) # book_dict_list 為列表

  JsonResponse(book_dict_list,safe = False)

3.關係屬性欄位的三種方式
    1.hbook = PrimaryKeyRelatedField(read_only = True)
    2.hbook = StringRealtedField(read_only=True)
    3.hbook = bookinfoSerializer(read_only = True)
    4.heroinfo_set = PrimaryKeyRelatedField(read_only = True,many = True)
    5.heroinfo_set = StringRealtedField(read_only=True,many = True)
    6.heroinfo_set = bookinfoSerializer(read_only = True,many = True)

4.獲取序列化後的資料:serializer.data ========> {}  or  [{},{},{}]

2.反序列化輸入:

1.驗證

2.驗證的呼叫
    1.接收資料(繼承APIView)
        next = request.query_params.get(`next`) :獲取查詢字串中的某個引數值
        data_dict = request.query_params.dict():獲取查詢字串中的所有值,返回一個字典
        data=request.data:獲取請求體中的引數(包括表單,json)

    2.建立序列化器物件serializer = 類(data = 字典)
    3.serializer.is_valid()=======>進行驗證===>True/False
        return JsonResponse(serializer.errors)
    4.serializer.errors===========>字典,異常資訊(定義序列化器裡面自定義的異常資訊)
    serializer.validated_data
3.儲存

4.儲存的呼叫
    1.serializer=序列化器型別(data=***)===>預設選擇create()方法
    2.serializer=序列化器型別(模型類物件,data=***,[partial = True])====>預設選擇update()方法
    3.book = serializer.save() # 返回一個物件

5.序列化輸出

3.APIView=============================================>繼承自View

1.由來 : 發現View中每個方法裡面都需要使用json轉換,可以進一步封裝

2.裡面的方法
    get
    post
    put
    patch
    delete
3.response和resquest
    1.request.query_params.get()=======>獲取查詢字串中的值,型別為字典
      request.data.get()======>獲取請求報文體中的資料,型別為字典
    2.Response()   {} or [{},{},{},{}]  不需要safe = False

4.繼承自View
    1.使用Resquest
    2.使用Response
    3.更好的異常處理
    4.在dispatch()前,進行了身份認證,許可權判斷,流量控制

3306 6379

4.GenericAPIView=================================>繼承自APIView

1.由來: 發現繼承自View的APIView,雖然已經減少了很多程式碼的重複,但是發現每個方法中只有
       查詢的模型類物件,和要操作的序列化器名不一樣,可以進一步封裝

2.GenericAPIView+5個ModelMixin
    from rest_framework.mixin import *
    from rest_framework.generics import GenericAPIView
    查詢多個(get)-------------------------------->list------>ListModelMixin
    建立(post)----------------------------------->create---->CreateModelMixin


    查詢一個(接收主鍵)(get)---------------------->retrieve-->RetrieveModelMixin
    修改(接收主鍵)(put)-------------------------->update---->UpdateModelMixin
    刪除(接收主鍵)(delete)----------------------->destory--->DestoryModelMixin

3.新新增的屬性和方法
    1.屬性:
        queryset
        serializer_class
        lookup_fileds------>預設為pk,因為有的方法接收主鍵的引數為pk(來自?P<pk>)

    2.方法:
        1.get_queryset()----->獲取屬性queryset的值,可重寫
               重寫場景 ----->比如說:需要修改"當前使用者"的收貨地址--->根據使用者查詢收貨地址
               原因分析 ----->1.類建立的時候沒有request物件--->2.執行get中的list()方法才會有request

        2.get_serializer_class()--->獲取屬性serializer_class的值,可重寫
               重寫場景 ----->不同情境選擇不同的序列化器

        3.get_serializer()-------------->獲取序列化器的物件------------>基本用不著
        4.get_object()------------------>獲取根據pk查詢到的物件-------->基本用不著


4.使用方法
    class HerosView(ListModelMixin,CreateModelMixin,GenericAPIView):
        # 自己指定查詢語句
        queryset  =HeroInfo.object.all()
        # 自己指定序列化器
        serializer_class = HerInfoModelSerializer

        def get(self,request):
            # 查詢所有:自己指定查詢語句+序列化器
            return self.list(request)

        def post(self,request):
            # 建立一個:自己指定序列化器
            return self.create(request)

5.組合繼承:========================>對GenericAPIView+5個ModelMixin的進一步封裝,不需要寫get,post,put,delete方法了

1.由來: 發現GenericAPIView+ModelMixin的每個方法裡面都是返回對應的操作,如 return self.list(request)
                                                                         return self.create(request),可以進一步封裝

HerosView
    list------------->ListAPIView----------------->繼承自ListModelMixin+GenericAPIView
    create----------->CreateAPIView--------------->繼承自CreateModelMixin+GenericAPIView
    list+create------>ListCreateAPIView----------->同理

HerosView
    retrieve--------->RetrieveAPIView
    update----------->UpdateAPIView
    destory---------->同理

    retrieve+update--------------->同理
    retrieve+destory-------------->同理
    # update+destory-------------->無
    retrieve+update+destory------->同理

6.檢視集

1.由來: 發現組合繼承(ListAPIView,ListCreateAPIView)中除了HerosView和HeroView不同以外,其他的都一樣,可以進一步封裝

2.合併的問題:在同一個了類中,不允許有同名的方法

3.解決問題:改方法的名稱

4.新問題:如果改了名稱,則dispatch()無法根據請求方法獲取方法

5.新的解決問題: {"get":"list"},可自定義方法名了

6.字典的傳入方法:views.HeroInfoViewSet.as_view({"get":"list"})

7.會多出一個action屬性: if self.action == "list"
----------------------------------------------------------------------------
8.drf中預設的設定好的方法
    list     create 
    get      update     destory

9.drf提供的檢視集-->4個

7.總結:


1.一步步封裝:
    APIView: 發現View中每個方法裡面都需要使用json轉換,可以進一步封裝發現View中每個方法裡面都需要使用json轉換,可以進一步封裝
    GenericAPIView+5個ModelMixin: 發現繼承自View的APIView,雖然已經減少了很多程式碼的重複,但是發現每個方法中只有
       查詢的模型類物件,和要操作的序列化器名不一樣,可以進一步封裝
    組合繼承: 發現GenericAPIView+ModelMixin的每個方法裡面都是返回對應的操作,如 return self.list(request)
                                                                         return self.create(request),可以進一步封裝
    檢視集: 發現組合繼承(ListAPIView,ListCreateAPIView)中除了HerosView和HeroView不同以外,其他的都一樣,可以進一步封裝


2.繼承關係(---->)如下:
                                                         ---->ListAPIView---->ListModelMixin+GenericAPIView
                                                         |
                                                         |--->CreateAPIView-->CreateModelMixin+GenericAPIView
    View----->APIView-----> GenericAPIView+5個ModelMixin |
                                                         |..........
                                                         |
                                                         |
                                                         ---->一共9個

3.是檢視的選擇:
    APIView==========================>自己實現,不涉及模型類的操作
    GenericAPIView+5個ModelMixin:====>增刪改查 部分操作

相關文章