rest_framework -- mixins&generics

来源:https://www.cnblogs.com/zhuchunyu/archive/2018/12/23/10165093.html
-Advertisement-
Play Games

上面的mixins、generics都是rest_framework里的模塊,我們可以繼承其中的某些類,達到代碼量減少的效果,這裡充分體現出了面向對象的繼承 一、mixins模塊 二、generics模塊 三、通過一個簡單的例子,順帶寫mixins,generics的用處 ...


上面的mixins、generics都是rest_framework里的模塊,我們可以繼承其中的某些類,達到代碼量減少的效果,這裡充分體現出了面向對象的繼承

一、mixins模塊

mixins  : from rest_framework import mixins #導入方式
          存放一些增刪改查的一些類  
          CreateModelMixin,ListModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin

二、generics模塊

generics: from rest_framework import generics # 導入方式
          首先mixins文件中就是一個一個類,寫著某些方法,但是你想用於CBV,必須繼承django的View,這裡我們用rest_framework則需繼承APIView,
          這個py文件里定義了許多類,但是有一個最基本的類GenericAPIView(views.APIView),裡面其他的類都會繼承這個類,因為這個類定義的一些
          方法是專門提供於mixins文件里的類的,再看其他generics模塊里的其他類,你會發現那麼類全是基於mixins模塊和GenericAPIView之間的組
          合,那麼你想用rest_framework提供給我們的簡便方法,那麼必須要繼承GenericAPIView,和mixins模塊里的類。

三、通過一個簡單的例子,順帶寫mixins,generics的用處

eg:寫一個介面,獲取到所有書籍的數據,這裡我只寫視圖類里的代碼
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin
from app import models
from write_serializers import BooksSerializers

class Books(GenericAPIView,ListModelMixin):
    queryset = models.Book.objects.all()
    serializer_class = BooksSerializers

    def get(self,request,*args,**kwargs):
        return self.list(request, *args, **kwargs)
好了,上面就是我們通過rest_framework提供的方法之一,完成了一個簡單的介面,
來一個GET請求,便會執行這個視圖類的get方法,最終返回了self.list方法的執行結果,那我們去看看list方法是怎麼執行的,
那麼我們順著繼承的基類去找list方法,基於深度查詢,我們找完GenericAPIView繼承的基類們,並沒有找到,那麼我們去ListModelMixin
這個類中找,這個類很簡單,就寫了一個list方法。

   

先看list方法,裡面有self.filter_queryset(),self.paginate_queryset(),self.get_serializer()等等方法,很明顯視圖類中
沒有寫這些方法,ListModelMixin這個類里也沒有,那麼肯定在GenericAPIView,所以我之前就說了,GenericAPIView類是為mixins模塊里
類提供方法的,所以二者必須一起使用。
分析1: queryset = self.filter_queryset(self.get_queryset())
queryset = self.filter_queryset(self.get_queryset())
這行代碼整體意思應該能看得懂吧,filter_queryset這個方法的返回值賦值給queryset,而filter_queryset的參數是get_queryset
的返回值,那麼我們先去看filter_queryset這方法的參數是什麼,也就是get_queryset的返回值
  
首先,斷言self.queryset這個屬性的布爾值必須是True的,不是的話便會拋異常,我們先看GenericAPIView類中有沒有這個屬性(這並不是 屬性的查找順序),我們可以找到queryset = None,這樣的話,我們再寫視圖類的話(前提是繼承了這個類),沒有寫queryset這個屬性或者值 為False,那麼便會出錯,所以queryset這個屬性必須在視圖類中為True。 根據這個我想到一點分享下,你可以用斷言這種方法,指定它的子類必須要有該屬性且值為True,對吧,方法也是一樣,定義一個方法,在該方法 內寫一個raise異常,rest_framework里很多就是通過這種方法,比如rest_framework.throttling.BaseThrottle這個類里的方法為allow_request。
接著上面繼續,能走到return,就代表self.queryset肯定為True吧,前面的邏輯處理就不多說了。從現在看的話,那麼這個queryset可以為 任何值吧,參數的值是什麼了,繼續看self.filter_queryset()這個方法的返回值
  
這個你可以看它的註釋,大概意思是將傳來的參數queryset,再過濾一遍,self.filter_backends它的值為None,前提不進行任何設置,而 這個設置是在settings文件里的REST_FRAMEWORK,也就是之前進行全局設置登陸認證,許可權認證的地方。不進行設置的話,還是會返回之前的 傳進來的參數。最終賦值給queryset
分析2:page = self.paginate_queryset(queryset)
page = self.paginate_queryset(queryset)
參數我們知道是什麼,直接看paginate_queryset方法吧

self.paginator它是被裝飾成屬性的方法,self.paginator它的返回不是None就是一個對象(這個對象是進行分頁的),上面我們列舉的例子
視圖類中並沒有寫pagination_class這個屬性,那麼就會去找到預設pagination_class,預設值為None,如果你再視圖類中寫了該屬性,
值應該是是一個類,最後會返回這個類的對象回去。如果self.paginator為True,那麼self.paginator就是一個對象了,就會執行該對象
下麵的paginate_queryset這個方法。
提醒:不管self.paginator這個對象是自定義的類產生的,還是rest_framework自帶的,那麼肯定會有paginate_queryset方法。它的返
          回值肯定是某一頁的對象列表。
分析3:serializer = self.get_serializer(queryset, many=True)
不管有沒有進行分頁,都會執行get_serializer這個方法,返回值為serializer,最終返回serializer.data
不難可以看出,我們寫的視圖類中必須要有serializer_class屬性,且有值,這個和前面queryset這屬性是一樣的。最終返回序列化的對象


總結下:我們寫的視圖類必須要有serializer_class --->> 寫序列化類
                                        queryset  ---->> queryset的對象
             可有可無看需求:pagination_class ---->>   進行分頁的類
在GenericAPIView還有一個方法再說下get_object方法,這個方法在RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin都用上了,看方法名就差不多知道,返回一個對象。
         
            分析1: queryset = self.filter_queryset(self.get_queryset()) 這個跟之前分析的一樣,(見上面的分析1)
            
            分析2: lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
                   這個其實沒啥好說的,就說一點or,and的用法,我博客也寫了這個,可以去看看
                   
            分析3: lookup_url_kwarg in self.kwargs
                   這句話很簡單,判斷lookup_url_kwarg這個值在不在self.kwargs這個容器里,但是這個self.kwargs到底是什麼呢?self就是
                   當前的視圖類的對象,它有kwargs這個屬性?
                   先自己思考下,我在後面再寫出來
                   
            分析4: obj = get_object_or_404(queryset, **filter_kwargs)
                   首先我們要弄清傳的參數的是什麼,filter_kwargs是一個字典({'pk':1}),那麼**filter_kwargs就是pk=1,queryset這個就不
                   用在介紹了,看看這個方法get_object_or_404,
                  
                    利用get方法,如果get里的參數不能找到唯一的一條數據的話,便會拋異常,通過捕捉異常去處理。程式順利進行的話,那麼返回的就是get
                    到的對象。
                    註意:屬性的查看順序,不要直接ctrl+滑鼠左鍵,上面這個方法我就是直接ctrl+左鍵點進去的,雖然最後還是執行的這個方法,但是這是
                         誤打誤撞,在generics這個模塊里,就有get_object_or_404方法。所以先去generics這個模塊里get_object_or_404,再去
                         上面的get_object_or_404方法。。。
                         
            分析5: self.check_object_permissions(self.request, obj)
                   上面這行代碼其實很熟悉,這個和之前進行用戶許可權認證差不多一樣,不一樣的是對誰進行許可權認證,一個是用戶,一個是一條記錄(數據
                   庫),也就是這裡的obj。
                   
                    permission就是一個進行許可權認證的對象,那麼該對象必須要有has_object_permission方法,進行一系列判斷,許可權許可的話,
                    就返回True,不許可的話,返回False。光這麼說,也不知道用在哪個地方,我想了個例子:首先obj就是我們從資料庫拿到的數據
                    (對象),其實數據也分等級,也有不同許可權的數據,我們可以再根據判斷,再進行數據的返回。
                    提醒:這裡我們是繼承了GenericAPIView,它裡面的get_object里做的許可權認證,我們不繼承GenericAPIView,也一樣可以去
                         調用這個方法。但check_object_permissions方法是rest_framework提供的。
        
            對於get_object方法的分析差不多了,再講上面的分析3,self.kwargs哪裡來的。
            我們回到APIView中的dispatch方法就知道了
 generics這個模塊里還有其他類,可以去看看,很簡單就是類的繼承問題。
好了,這塊就寫到這裡了

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

-Advertisement-
Play Games
更多相關文章
  • 簡介 本系列基於 的官方文檔,除去了文檔中一些冗餘的東西,加上了一些自己的理解,意圖是在於幫助更多初識 的人來進行一次探險。 本系列建議具有Java基礎和Spring使用經驗的同學學習。 什麼是Spring Boot 在使用之前,我們先來看看 到底是個啥,從字面意義上去理解,是Spring的一個引導 ...
  • 一、spring概述 Spring是一個開放源代碼的設計層面框架,他解決的是業務邏輯層和其他各層的松耦合問題,因此它將面向介面的編程思想貫穿整個系統應用。Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson創建。簡單來說,Spring是一個分層的JavaSE/E ...
  • 偶然看到一篇100多行實現SpringMvc的博客,閱讀後整理加實現出來。大家共勉!(紙上得來終覺淺,絕知此事要躬行。) 實現Spring的部分。 代碼解析如下: 1、首先創建Servelt,繼承HttpServlet。覆蓋init/doGet/doPost方法。 2、配置web.xml 2.1、配 ...
  • Python類練習 定義一個類 列印Point: Point實例化為一個p1: 我們直接列印 結果為 __main__.Point` 給實例p1添加屬性 (3, 4) 原點(0, 0)與p1之間的距離:5.0 (3, 4) 定義矩形 實例化一個例子r1 (100, 200) 列印矩形的寬度width ...
  • 這篇文章一起來回顧複習下spring的事務操作.事務是spring的重點, 也是面試的必問知識點之一. 說來這次面試期間,也問到了我,由於平時用到的比較少,也沒有關註過這一塊的東西,所以回答的不是特別好,所以借這一篇文章來回顧總結一下,有需要的朋友,也可以點贊收藏一下,複習一下這方面的知識,為年後的 ...
  • 我們可以在application.properties中配置自定義的屬性值,為了獲取這些值,我們可以使用spring提供的@value註解,還可以使用springboot提供的@ConfigurationProperties註解非常方便的完成屬性值的註入。 ...
  • 剛開始接觸 python 的時候,對 python 中的 wargs (可變參數) 和 kwargs (關鍵字參數)的理解不是很透徹,看了一下 《Explore Python》一書,裡面對這一部分的描述相對淺顯易懂, 這裡依據個人理解進行相關總結。 可變參數( args) 對於可變參數可以聯想到 C ...
  • 一.函數調用 在python中內置了很多函數,我們可以直接調用 。想要調用函數首先要知道函數的名稱及包含的參數,還可以通過查看python官方的文檔:https://docs.python.org/3/library/functions.html 就拿abs()函數來舉例 用來返回數值的絕對值 >> ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...