drf框架相關

drf框架: django-rest framework 1.接口:聯繫兩個物質的媒介,完成信息交互
    web程序中:聯繫前臺頁面與後臺數據庫的媒介,已完成信息的交互;
    web接口組成:
        url:長得像放回數據的url連接
        請求參數:前臺按照指定的key提供數據給後臺
        響應數據:後臺與數據庫交互後將數據反饋給前臺 
2.restful接口規範 -> 規範化書寫接口
    定義:爲了採用不一樣的後臺語言,也能用一樣的接口來獲取到一樣的數據;
    接口文檔: 寫接口要寫 url,響應數據
        注:若是將請求參數也歸入考量範圍,那就是寫接口文檔
        
    .url:
        1.用api關鍵字標識接口url     eg:api.baidu.com | www.baidu.com/api
        2.接口數據安全性決定優先選擇https協議
        3.若是一個接口有多版本存在,須要在url中標識提現
           eg:    api.baidu.com/v1/...   | api.baidu.com/v2/...
        4.接口操做的數據源稱之爲資源,在url中通常採用資源複數形式,
          一個接口能夠歸納對該資源的多種操做方式
          api.baidu.com/books | api.baidu.com/books/(pk)
        5.請求方式有多種,如何用一個url處理保證不混亂?
          --經過請求方式標識操做資源的方式
              /books        get            獲取全部
            /books        post        增長一個(多個)
            /books/(pk)    delete        刪除一個
            /books/(pk)    put            總體更新一個
            /books/(pk)    patch        局部更新一個
                  
                  
        6.資源每每涉及數據的各類操做方式 --篩選,排序,限制
            eg: api.baidu.com/books/?search=系&ordering=price&limit=3
            
    .響應數據:
        1.http請求的響應會有不一樣的狀態碼,接口用來返回操做的資源數據
            status  0(操做資源成功)  1(操做資源失敗)  2(操做資源成功,但沒匹配結果)
            注:資源狀態碼不像http狀態碼,通常都是後臺與前臺約定的
        2.資源的狀態碼文字提示
            status  ok  子帳號有誤'   '密碼有誤'   '用戶鎖定'
        3.資源自己
            results
            注: 刪除資源成功不作任何數據返回
            
        4.不能直接放回的資源(子資源,圖片,視頻),返回資源的連接
3.cbv生命週期源碼  --基於restful規範下的cbv接口
基礎接口:
    #主路由:url.py
        from django.conf.urls import url, include
        from django.contrib import admin
        urlpatterns = [
            url(r'^admin/', admin.site.urls),
            # 路由分發
            url(r'^api/', include('api.urls'))
        ]
    #api組件的子路由:api/url.py
        from django.conf.urls import url
        from . import views
        urlpatterns = [
            url(r'^books/', views.Book.as_view()),
            url(r'^books/(?P<pk>.*)/$', views.Book.as_view()),
        ]
    #模型層:model.py
        from django.db import models
        class Book(models.Model):
            title = models.CharField(max_length=64)
            price = models.DecimalField(max_digits=5, decimal_places=2)
            class Meta:
                db_table = 'old_boy_book'
                verbose_name = '書籍'
                verbose_name_plural = verbose_name
            def __str__(self):
                return '《%s》' % self.title
    #後臺層:admin.py
        from django.contrib import admin
        from . import models
        admin.site.register(models.Book)

    #數據庫遷移
         python manage.py makemigrations
         python manage.py migrrate
         #註冊超級管理員
         python manage.py createsuperuser
    #視圖層:views.py
        from django.http import JsonResponse
        from django.views import View
        from . import models
            class Book(View):
                def get(self, request, *args, **kwargs):
                    pk = kwargs.get('pk')
                    if not pk:  # 羣查
                        # 操做數據庫
                        book_obj_list = models.Book.objects.all()
                        # 序列化過程
                        book_list = []
                        for obj in book_obj_list:
                            dic = {}
                            dic['title'] = obj.title
                            dic['price'] = obj.price
                            book_list.append(dic)
                        # 響應數據
                        return JsonResponse({
                            'status': 0,
                            'msg': 'ok',
                            'results': book_list
                        }, json_dumps_params={'ensure_ascii': False})
                    else:  # 單查
                        book_dic = models.Book.objects.filter(pk=pk).values('title', 'price').first()
                        if book_dic:
                            return JsonResponse({
                                'status': 0,
                                'msg': 'ok',
                                'results': book_dic
                            }, json_dumps_params={'ensure_ascii': False})
                        return JsonResponse({
                            'status': 2,
                            'msg': '無結果',
                        }, json_dumps_params={'ensure_ascii': False}
    1.獲取一個
    2.獲取全部
    3.增長一個
    4.刪除一個
    5.總體更新一個
    6.局部更新一個
    羣增|羣刪|總體改羣改|局部改羣
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if not pk:  # 羣查
                # 操做數據庫
                book_obj_list = models.Book.objects.all()
                # 序列化過程
                book_list = []
                for obj in book_obj_list:
                    dic = {}
                    dic['title'] = obj.title
                    dic['price'] = obj.price
                    book_list.append(dic)
                # 響應數據
                return JsonResponse({
                    'status': 0,
                    'msg': 'ok',
                    'results': book_list
                }, json_dumps_params={'ensure_ascii': False})
            else:  # 單查
                book_dic = models.Book.objects.filter(pk=pk).values('title', 'price').first()
                if book_dic:
                    return JsonResponse({
                        'status': 0,
                        'msg': 'ok',
                        'results': book_dic
                    }, json_dumps_params={'ensure_ascii': False})
                return JsonResponse({
                    'status': 2,
                    'msg': '無結果',
                }, json_dumps_params={'ensure_ascii': False})
                
Postman接口工具:    
postman能夠完成不一樣方式的請求: get|post|put...
get請求,攜帶參數採用Params,
post請求提交數據包有三種方式:form-data | urlencoding | json
原生django對urlencoding方式數據兼容最好
    def post(self, request, *args, **kwargs):
        # 前臺經過urlencoding方式提交數據
        try:
            book_obj = models.Book.objects.create(**request.POST.dict())
            if book_obj:
                return JsonResponse({
                    'status': 0,
                    'msg': 'ok',
                    'results': {'title': book_obj.title, 'price': book_obj.price}
                }, json_dumps_params={'ensure_ascii': False})
        except:
            return JsonResponse({
                'status': 1,
                'msg': '參數有誤',
            }, json_dumps_params={'ensure_ascii': False})

        return JsonResponse({
            'status': 2,
            'msg': '新增失敗',
        }, json_dumps_params={'ensure_ascii': False})


DRF框架:
    安裝: pip install djangorestframework
    drf框架規矩的封裝風格:
        from rest_framework.views import APIView
        from rest_framework.response import Pesponse
        from rest_framework.request import Request
        from rest_framework.serializers import Serializer
        from rest_framework.settings import APISettings
        from rest_framework.filters import SearchFilter
        from rest_framework.pagination import PageNumberPagination
        from rest_framework.authentication import TokenAuthentication
        from rest_framework.permissions import IsAuthenticated
        from rest_framework.throttling import SimpleRateThrottle
        
    class Test(APIView):
        def get(self, request, *args, **kwargs):
            return Response('drf get ok')
    
    drf請求生命週期:
        1.請求走的是APVIiew 的 as_view函數
        2.在APIView的 as_view 調用父類(django原生)的as_view,還禁用了 csrf 認證
        3.在父類的 as_view中dispatch方法請求走的又是APIV接個人dispatch
        4.完成任務方法交給視圖類的請求函數處理,獲得請求的響應結果,返回給前臺

    請求模塊: request對象:
        源碼入口:APIView類的dispatch方法中:
        源碼分析:
            #二次封裝獲得def的request對象
            request = self.initialize_request(request,*args,**kwargs)
            #在rest_framework.request.Request實例化方法中
            self_request = request 將request做爲新request的_request屬性
            #在rest_framework.request.Request的__getattr__方法中
            try:
                return getattr(self._request,attr) #訪問屬性徹底兼容原生request
            except AttributeError:
                return self.__getattrigute__(attr)

        小結:
            1.drf對原生request作了二次封裝,request._request就是原生request
            2.原生request對象的屬性和方法均可以被drf的request對象直接訪問(兼容)
            3.drf請求的全部url拼接參數均被解析到query_params中,全部數據包數據都被解析到data中 
            
        class Test(APIView):
            def get(self, request, *args, **kwargs):
                # url拼接的參數
                print(request._request.GET)  # 二次封裝方式
                print(request.GET) # 兼容
                print(request.query_params) # 拓展

                return Response('drf get ok')

            def post(self, request, *args, **kwargs):
                # 全部請求方式攜帶的數據包
                print(request._request.POST)  # 二次封裝方式
                print(request.POST)  # 兼容
                print(request.data)  # 拓展,兼容性最強,三種數據方式均可以

                print(request.query_params)

                return Response('drf post ok')


    渲染模塊:瀏覽器和Postman請求結果渲染數據的方式不同
        源碼入口:APIView類的dispatch方法中:self.response = self.finalize_response(request, response, *args, **kwargs)
        源碼分析:
            #解析reponse對象數據
            self.response = self.finalize_response_response(request,response,*args,**kwargs)點進去
            #拿到運行的解析類的對象萌:
            neg = self.perform_content_negotiation(request,force=True) 點進去
            #獲取解析類對象
            renderers = self.get_genderers() 點進去
            #從視圖類中獲得renderer_classes請求類,如何實例化一個個對象形參解析類對象列表
            return [renderer() for renderer in self.renderer_classes]
    
    重點:self.renderer_classes獲取renderer_rendererd_classes的順序
        1.本身視圖類的類屬性(局部配置) =>
        2.APIView類的類屬性設置 =>
        3.本身配置文件的DEFAULT_RENDERER_CLASSES(全局配置) =>
        4.drf配置文件的DEFAULT_RENDERER_CLASSES
        
    全局配置:全部視圖類統一處理,在項目的settings.py中    
        REST_FRAMEWORK = {
            # drf提供的渲染類
            'DEFAULT_RENDERER_CLASSES': [
                'rest_framework.renderers.JSONRenderer',
                'rest_framework.renderers.BrowsableAPIRenderer',
            ],
        }
    局部配置:某一個或一些實體類單獨處理,在views.py視圖類中提供對應的類屬性
        from rest_framework.renderers import JSONRenderer
        class Test(APIView):
            def get(self, request, *args, **kwargs):
                return Response('drf get ok')

            def post(self, request, *args, **kwargs):
                return Response('drf post ok'
        class Test2(APIView):
            # 局部配置
            renderer_classes = [JSONRenderer]
            def get(self, request, *args, **kwargs):
                return Response('drf get ok 2')

            def post(self, request, *args, **kwargs):
                return Response('drf post ok 2')
    


4.請求組件,解析組件,響應組件
5.序列化組件(靈魂)
6.三大認證(*****************)
    --認證,權限(權限六表),頻率
7.其餘組件:過濾,篩選,排序,分頁,路由  
    注:難點在源碼分析
相關文章
相關標籤/搜索