基類是父類還是子類,DRF基類APIView的子類GenericAPIView

 2023-12-25 阅读 28 评论 0

摘要:DRF的基類是APIView類,GenericAPIView類是APIView類的子類。 基類是父類還是子類,GenericAPIView類有什么存在的意義呢? 其實, 他主要提供了兩個用處: 1.提供關于數據庫查詢的屬性與方法 2.提供關于序列化器使用的屬性與方法 ===

DRF的基類是APIView類,GenericAPIView類是APIView類的子類。

基類是父類還是子類,GenericAPIView類有什么存在的意義呢?

其實,

他主要提供了兩個用處:

1.提供關于數據庫查詢的屬性與方法

2.提供關于序列化器使用的屬性與方法

=================================================================================================================

詳解:

先看一段小代碼比較好理解,(繼承APIView與繼承GenericAPIView的兩種不同的寫法,查詢多條數據時)

繼承APIView的寫法:

class DepartmentListAPIView(APIView):def get(self,request):"""查詢多條數據"""dep = Department.objects.all()# 創建序列化器對象serializer = DepartmentSerializer(instance=dep,many=True)# 序列化:對象->字典data_dict = serializer.data# DRF的Response對象可以把字典轉換為請求頭指定的格式返回return Response(data=data_dict)

?

繼承GenericAPIView的寫法:

class DepartmentListAPIView(GenericAPIView):# querset與serializer_class是固定名字的!一定要指定# queryset指定數據庫全部數據的查詢集queryset = Department.objects.all()# serializer_class指定序列化器serializer_class = DepartmentSerializerdef get(self,request):"""查詢多條數據"""dep = self.get_queryset()serializer = self.get_serializer(dep,many=True)data_dict = serializer.datareturn Response(data=data_dict)

?

1.提供關于數據庫查詢的屬性與方法:

上面例子中,get_queryset()的方法,可以取得數據庫查詢結果的查詢集queryset的內容。(注意,一定要通過get_query取得數據庫查詢的結果后再傳給序列化器,不能直接傳self.queryset給序列化器,因為get_query的源碼還有“Ensure queryset is re-evaluated on each request.”這一個步驟。)

?

2.提供關于序列化器使用的屬性與方法

上面的列子中,get_serializer()的方法,實際上就是取類屬性serializer_class的值

?

  • 更多的繼承APIView與繼承GenericAPIView的寫法:

繼承APIView的寫法:

class DepartmentListAPIView(APIView):def get(self,request):"""查詢多條數據"""dep = Department.objects.all()# 創建序列化器對象serializer = DepartmentSerializer(instance=dep,many=True)# 序列化:對象->字典data_dict = serializer.data# DRF的Response對象可以把字典轉換為請求頭指定的格式返回return Response(data=data_dict)def post(self,request):"""新增一條數據"""# DRF的Request對象直接把接受到的值轉換為字典data_dict = request.data# 創建序列化器對象serializer = DepartmentSerializer(instance=None,data=data_dict)# 校驗校驗不通過,拋異常(反序列化的功能)serializer.is_valid(raise_exception=True)# 反序列化,把字典的數據存進數據庫
        serializer.save()# restful風格,新增要返回新增數據的那一列內容。用了序列化,把對象轉換為字典,同時Response處理。return Response(data=serializer.data)class DepartmentDetailAPIView(APIView):def get(self,request,pk):"""查詢一條數據"""# 查詢出該條數據的對象try:dep = Department.objects.get(id=pk)except Department.DoesNotExist:return HttpResponse(status=status.HTTP_404_NOT_FOUND)# 創建序列化器對象serializer = DepartmentSerializer(instance=dep)# 序列化,把對象轉換為字典,同時Response根據請求頭返回相應的格式return Response(data=serializer.data)def post(self,request,pk):"""修改部門"""# DRF的Request對象直接把接受到的值轉換為字典data_dict = request.data# 查詢出要修改的數據try:dep = Department.objects.get(id=pk)except Department.DoesNotExist:return HttpResponse(status=404)# 創建序列化器對象serializer = DepartmentSerializer(instance=dep,data=data_dict)# 反序列化,校驗參數是否正確,若不正確,拋異常serializer.is_valid(raise_exception=True)# 反序列化,把字典的數據存進數據庫
        serializer.save()# 序列化,把對象轉換為字典。同時DRF的Response對象根據請求頭返回相應的格式return Response(serializer.data)def delete(self,request,pk):"""刪除一個部門"""try:dep = Department.objects.get(id=pk)except Department.DoesNotExist:return HttpResponse(status=404)dep.delete()return Response(status=status.HTTP_204_NO_CONTENT)

?

繼承GenericAPIView的寫法:

class DepartmentListAPIView(GenericAPIView):# querset與serializer_class是固定名字的!# queryset指定數據庫全部數據的查詢集queryset = Department.objects.all()# serializer_class指定序列化器serializer_class = DepartmentSerializerdef get(self,request):"""查詢多條數據"""dep = self.get_queryset()serializer = self.get_serializer(instance=dep,many=True)data_dict = serializer.datareturn Response(data=data_dict)def post(self,request):"""新增一條數據"""data_dict = request.dataserializer = self.get_serializer(instance=None,data=data_dict)serializer.is_valid(raise_exception=True)serializer.save()return Response(serializer.data)class DepartmentDetailAPIView(GenericAPIView):queryset = Department.objects.all()serializer_class = DepartmentSerializerdef get(self,request,pk):"""查詢一條數據"""dep = self.get_object()  # 有主鍵用get_object(),get_object()方法根據pk參數查找queryset中的數據對象serializer = self.get_serializer(instance=dep)return Response(data=serializer.data)def post(self,request,pk):"""修改部門"""data_dict = request.datadep = self.get_object()serializer = self.get_serializer(instance=dep,data=data_dict)serializer.is_valid(raise_exception=True)serializer.save()return Response(serializer.data)def delete(self,request,pk):"""刪除一個部門"""dep = self.get_object()dep.delete()return Response(status=status.HTTP_204_NO_CONTENT)

?

?

  • 總結:

從上面的代碼可以看出,繼承APIView和繼承GenerciAPIView的代碼量基本差不多。那么GenericAPIView這個類有什么實質的用處呢?

其實,

他是只是為了提供幾種方法給它的擴展類而已,GenericAPIView通常結合一個或多個Mixin擴展類使用,用來快速地實現列表視圖與詳情視圖。

?

轉載于:https://www.cnblogs.com/chichung/p/9940697.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/194921.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息