python之Django rest_framework總結

来源:https://www.cnblogs.com/mengqingjian/archive/2018/02/17/8451978.html
-Advertisement-
Play Games

一、rest api a、api就是介面 如: - http://www.oldboyedu.com/get_user/ - http://www.oldboyedu.com/get_users/ b、api的兩個用途 1、為別人提供服務 2、前後端分離 二、restful a、--字面意思:表徵狀 ...


一、rest api

   a、api就是介面

        如: - http://www.oldboyedu.com/get_user/

               - http://www.oldboyedu.com/get_users/

   b、api的兩個用途

        1、為別人提供服務

        2、前後端分離

二、restful

    a、--字面意思:表徵狀態轉移

    b、面向資源編程,對互聯網上的任意東西都視為資源

         如:- http://www.oldboyedu.com/get_user/

                - http://www.oldboyedu.com/get_img/1.png

三、restful規範

     a、 ---URL

     b、 ---url名詞

路徑,視網路上任何東西都是資源,均使用名詞表示(可複數)
  https://api.example.com/v1/zoos
  https://api.example.com/v1/animals
  https://api.example.com/v1/employee

    c、 ---status狀態碼

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

   d、---提交方式

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

   e、  ---錯誤信息

狀態碼是4xx時,應返回錯誤信息,error當做key。
{
    error: "Invalid API key"
}

   f、 ---版本

   g、 ---Hypermedia link,RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什麼。

   h、---功能變數名稱

   j、---過濾,通過在url上傳參的形式傳遞搜索條件

  k、 ---返回結果,針對不同操作,伺服器向用戶返回的結果應該符合以下規範

GET /collection:返回資源對象的列表(數組)  
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔

rest_Framework的規範:

    按順序:它的method的不同,原來沒有考慮,原來是url區分,現在通過method來區分,method的不同提交方式不同,緊接著一般是面向資源的就是把url變成名詞,接下就是返回值,以前沒有考慮狀態碼,現在有考慮狀態碼。(一般有get,post方法,還有put,delete等方法)

四、 基於Django Rest Framework框架實現 

   a、安裝:pip3 install djangorestframework -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com

五、什麼是RESTful

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

      a、 django的中間件比rest_framework執行的早

      b、 認證的功能放到中間件也是可以做的

      c、認證一般做,檢查用戶是否存在,如果存在request.user/request.auth;不存在request.user/request.auth=None

      d、認證小總結:

  ---類:authenticate/authenticate_header

      ---返回值:None,元組(user,auth),異常

      ---配置:

                 ---視圖:                      

                                    class IndexView(APIView):
                                           authentication_classes = [MyAuthentication,]

                 ---全局                    

                                    REST_FRAMEWORK = {
                                                'UNAUTHENTICATED_USER': None,
                                                'UNAUTHENTICATED_TOKEN': None,
                                                "DEFAULT_AUTHENTICATION_CLASSES": [
                                                 # "app02.utils.MyAuthentication",
                                                ],
                                               }

六、許可權

    a、許可權才真正的做request.user/request.auth拿到它們做是否訪問的判斷

    b、許可權小總結: 

     ---類:       has_permission/has_object_permission

     ---返回值:True、False、exceptions.PermissionDenied(detail="錯誤信息")

     ---配置:

               ---視圖:                  

                                class IndexView(APIView):
                                       permission_classes = [MyPermission,]

                      ---全局:

                                REST_FRAMEWORK = {
                                "DEFAULT_PERMISSION_CLASSES": [
                                # "app02.utils.MyAuthentication",
                                 ],
                               }

七、限制訪問的頻率

    限制訪問頻率的應用:

   a、對匿名用戶進行限制,每個用戶1分鐘允許訪問10次

        在這裡用唯一標識:self.get_ident() 

   b、限制訪問的頻率小總結: 

  ---類:       allow_request/wait PS: scope = "wdp_user"

     ---返回值:True、False

     ---配置:

                  ---視圖:

                                            class IndexView(APIView):
                                                     throttle_classes=[AnonThrottle,UserThrottle,]
                                                     def get(self,request,*args,**kwargs):
                                                     self.dispatch
                                                     return Response('訪問首頁')

                   ---全局:

                                          REST_FRAMEWORK = {
                                                      "DEFAULT_THROTTLE_CLASSES":[
                                                   ],
                                                      'DEFAULT_THROTTLE_RATES':{
                                                      'wdp_anon':'5/minute',
                                                      'wdp_user':'10/minute',
                                                   }
                                                   }

、認證、許可權、限制訪問頻率返回結果的比較

    1、認證、許可權、限制訪問頻率這三個返回的結果:

     a、認證返回的三種結果:
            a、None
            b、元組(user,auth)
            c、異常 raise APIException(...)

     b、 許可權的返回值三種結果:

            a、True 有許可權
            b、False 沒許可權
            c、異常

     c、 限制訪問的頻率返回值的兩種結果:

            a、True 
            b、False

實例化:
v1 = ["view.xxx.path.Role","view.xxx.path.Group",]    可以迴圈,迴圈出來的每一個不能實例化
如果把v1迴圈弄成每一個對象列表,通過rsplit切割,在通過importlib.import_module拿到每一個路徑,在通過getattr把它的類名拿過來,
這個類加括弧就是實例化想
for item in v1:
m = importlib.import_module('view.xxx.path')
cls = getattr(m,'Role')
cls()



from view.xxx.path import Role,Group      
v2 = [Group,Role]      這個可以迴圈每一個實例化
for item in v2:     #迴圈V2的每一個元素加括弧,就是實例化
item()

九、Django rest_Framework框架

     a、  ----為什麼用Django rest_Framework框架?

----首先沒有Django rest_Framework框架用django也是可以做出來的,只不過它為我們提供一些API常用的功能,比如:(認證,許可權,限流,有了這些我們只需要寫個類已配置,
它就能當都市圖用,還能全局配置,如果自己寫還得寫中間件,寫裝飾器來實現,通過Django rest_Framework框架,他已經把規則寫好,只需要寫類,只需實現方法,返回值就可以)
實現了一部分功能。
----設計比較好 ----單獨視圖+全局配置 =>Dajngo中間件(importlib/反射)=>動態配置課擴展(簡訊,郵件,微信等提醒)

     b、Django rest_Framework原理?

             先開始在路由,路由.as_view,

             點擊as_view

             請求進來,走完以上,才走self.dispatch()

             走self.dispatch()流程如下地址:http://www.cnblogs.com/mengqingjian/p/8419563.html 

十、版本

    a、根據url的不同來來操作,版本控制

          先在setting中註冊

十一、rest framework解析器

    a、請求的數據進行解析:請求體進行解析。表示服務端可以解析的數據格式的種類。

Content-Type: application/url-encoding.....
            request.body
            request.POST
            
            Content-Type: application/json.....
            request.body
            request.POST
        
        客戶端:
            Content-Type: application/json
            '{"name":"alex","age":123}'
        
        服務端接收:
            讀取客戶端發送的Content-Type的值 application/json
            
            parser_classes = [JSONParser,]
            media_type_list = ['application/json',]
        
            如果客戶端的Content-Type的值和 application/json 匹配:JSONParser處理數據
            如果客戶端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser處理數據
        
        
        配置:
            單視圖:
            class UsersView(APIView):
                parser_classes = [JSONParser,]
                
            全局配置:
                REST_FRAMEWORK = {
                    'VERSION_PARAM':'version',
                    'DEFAULT_VERSION':'v1',
                    'ALLOWED_VERSIONS':['v1','v2'],
                    # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
                    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
                    'DEFAULT_PARSER_CLASSES':[
                        'rest_framework.parsers.JSONParser',
                        'rest_framework.parsers.FormParser',
                    ]
                }

十二、 rest framework序列化+Form

     a、序列化:

               對象 -> 字元串 序列化
               字元串 -> 對象 反序列化

     b、目的:
               解決QuerySet序列化問題

十三、為什麼要前後端分離

    a、因為前端它有自己框架,這樣它的效率就非常高

    b、不做前後端分離,公司如果既有客戶端,又有app這種情況下你就的寫兩遍

十四、django restful框架好處

  幫助我們寫了好多組件比如:

     a、認證:有類,類中的方法authenticate/authenticate_header,它的返回值有None,元組,異常。如果返回值為None那就不管,它是匿名用戶。

     b、許可權:有類,類中的方法:has_permission

     c、節流:有類,類的方法:allow_request,在這裡allow_request來表示限制,它是通過IP來限制,

 它的內部原理是:預設是IP,用戶來用IP,這個IP可能代理IP,IP或者是代理IP拿著請求頭預設放到大家能夠的緩存中                          
去,每一個人的IP為p,後面的那個列表存它的方位時間,每一次請求進來獲取它的當前時間根據時間的個數來比較,在
比較的過程中看看把不符合時間的個數來進行比較,能訪問就繼續,不能訪問就不要繼續。 

     d、版本:是url和hostname,他們兩個鐘每一個都有兩個方法一個是幫你拿版本另一個是幫你反向生成url

     e、解析器:用戶發過來的請求體數據進行操作

     f、序列化:兩個功能:序列化,校驗

十五、分頁

分頁的三種情況:

       a、記錄當前訪問頁的數據id

       b、最多顯示120頁

       c、對頁碼進行加密

a、基於limit offset做分頁

class P1(LimitOffsetPagination):
    
                max_limit = 3
                default_limit = 2
                limit_query_param = 'limit'
                offset_query_param = 'offset'
                        
            
            class IndexView(views.APIView):
                def get(self,request,*args,**kwargs):
                    user_list = models.UserInfo.objects.all()
                    p1 = P1()
                    page_user_list = p1.paginate_queryset(queryset=user_list, request=request, view=self)
                    ser = IndexSerializer(instance=page_user_list, many=True)
                    return Response(ser.data) # 不含上一頁和下一頁
                    # return p1.get_paginated_response(ser.data) # 含上一頁和下一頁
                    
            class IndexView(views.APIView):
                def get(self,request,*args,**kwargs):
                    ret = BaseResponse()
                    try:
                        user_list = models.UserInfo.objects.all()
                        p1 = P1()
                        page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
                        ser = IndexSerializer(instance=page_user_list,many=True)
                        ret.data = ser.data
                        ret.next = p1.get_next_link()
                    except Exception as e:
                        ret.code= 1001
                        ret.error = 'xxxx錯誤'
                    return Response(ret.__dict__)

 b. 基於頁碼的分頁

class P2(PageNumberPagination):
                # 每頁顯示的數據條數
                max_page_size = 5
                page_size = 2
                page_size_query_param = 'size'

                # 頁碼
                page_query_param = 'page'

十六、視圖

1、APIView

class IndexView(views.APIView):
                    def get(self, request, *args, **kwargs):
                        user_list = models.UserInfo.objects.all()
                        ser = IndexSerializer(instance=user_list,many=True)
                        return Response(ser.data)

2、GenericAPIview(APIView)

3、GenericViewSet(ViewSetMixin,generics.GenericAPIView)

路由修改:
                    urlpatterns = [
                        url(r'^index/$', views.IndexView.as_view({'get':'list','post':'create'})),
                        url(r'^index/(?P<pk>\d+)$', views.IndexView.as_view({'get':'retrieve'})),
                    ]
                
                視圖修改:
                    
                    class IndexView(viewsets.GenericViewSet):

                        def list(self,request,*args,**kwargs):

                             pass # 獲取列表信息

                        def retrieve(self, request, *args, **kwargs):
                            pass  # 獲取單條數據

                        def create(self,request, *args, **kwargs):
                            pass
                
                
                自定義:
                    
                        增
                            POST
                            /users/
                        刪
                            DELETE
                            /users/1/
                        改
                            PUT
                            /users/1/
                            
                            patch
                            /users/1/
                        查
                            GET
                            /users/ 
                            GET
                            /users/1/
                            
                        urlpatterns = [

                            url(r'^index/$', views.IndexView.as_view()),
                            url(r'^index/(?P<pk>\d+)$', views.IndexView.as_view()),
                        ]
                            
                        class IndexView(views.APIView):

                            def get(self,request,*args,**kwargs):
                                pk = kwargs.get('pk')
                                if pk:
                                    pass # 獲取單條信息
                                else:
                                    pass # 獲取列表信息

                            def post(self,request,*args,**kwargs):
                                pass

                            def put(self,request,*args,**kwargs):
                                pass

                            def patch(self,request,*args,**kwargs):
                                pass

                            def delete(self,request,*args,**kwargs):
                                pass

4、ModelViewSet

ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet)                
                
                class IndexView(ModelViewSet):

十七、 渲染器
    看到的頁面時什麼樣子的,返回數據。
    renderer_classes = [JSONRenderer,BrowsableAPIRenderer]

十八、跨域

   a、  瀏覽器的同源策略

              1、  ----對ajax請求進行阻攔

               2、 ----對href屬性讀不阻攔

       xhr=new XMLHttpRequest

       xhr.open...

       xhr.send(...)

    b、 解決方案:

         ---JSONP

                 點擊按鈕: 

                        動態添加一個

<script src='http://www.baidu.com/users/'></script>
                        <script>
                            function func(arg){
                                alert(arg)
                            }
                        </script

    c、刪除

<script src='http://www.baidu.com/users/'></script>

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JavaScript的數據類型 基本區分方法 ECMAScript標准定義了7種數據類型 6 種 基本類型: Boolean,兩種取值:true和false Null,一種取值:null Undefined,一種取值:undefined Number,JS的數值為基於 IEEE 754 標準的雙精度 ...
  • JDK8已經發佈快4年的時間了,現在來談它的新特性顯得略微的有點“不合時宜”。儘管JDK8已不再“新”,但它的重要特性之一——Lambda表達式依然是不被大部分開發者所熟練運用,甚至不被開發者所熟知。 國內的開發環境大家都知道,有各種的老項目,有各種各樣的發佈風險,讓公司以及項目組對新的技術往往望而 ...
  • 線程(上) 1.線程含義:一段指令集,也就是一個執行某個程式的代碼。不管你執行的是什麼,代碼量少與多,都會重新翻譯為一段指令集。可以理解為輕量級進程 比如,ipconfig,或者, python XX.py(執行某個py程式),這些都是指令集和,也就是各自都是一個線程。 2.線程的特性: 線程之間可 ...
  • 一、OGNL表達式 1.概述 ​ OGNL是Object-Graph Navigation Language的縮寫,俗稱對象圖導航語言. 它是一種功能強大的表達式語言,通過它簡單一致的表達式語法,可以存取對象的任意屬性,調用對象的方法,遍歷整個對象的結構圖,實現欄位類型轉化等功能。 ​ Eg: hi ...
  • 併發系統可以採用多種併發編程模型來實現。併發模型指定了系統中的線程如何通過協作來完成分配給它們的作業。不同的併發模型採用不同的方式拆分作業,同時線程間的協作和交互方式也不相同。這篇併發模型教程將會較深入地介紹目前(2015年,本文撰寫時間)比較流行的幾種併發模型。 併發模型與分散式系統之間的相似性 ...
  • static_cast 任何具有明確定義的類型轉換,只要不包含底層const,都可以使用static_cast。例如: int i = 3, j = 2; double slope = static_cast<double>(i) / j; static_cast還可以用於把void*轉換成別的類型 ...
  • pycharm是很強大的開發工具,但是每次註冊著實讓人頭疼。網路上很多註冊碼、註冊伺服器等等、但都只是一年或者不能用;為次有如下解決方案。親測有效!!! 如果想讓pycharm永久被激活,比如截止日到2099-12-31;這應該算是永久激活了吧; step1: 下載jar包: 此jar包的目的就是讓 ...
  • 已經鑽DELPHI很深了,當然現在DELPHI是過了最輝煌的時代。但為什麼要繼續下去,而不轉向其它的?這是不是死腦筋? 我看了一下C#的LINQ的產生,然後又被實體框架所代替。思考了一下: 1)LINQ的確是有好處,但是所用的場景又不多,這樣就會變得很雞肋。所以說學新的東西,有時對自己來說不一定有相 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...