DRF視圖
請求
# 見源碼
響應
# Response()參數:
# data,即要返回的數據,字典格式
# status,返回的狀態碼
# template_name,即自定義模板
# headers,即響應頭,可增加數據
# content_type,即響應編碼
# 根據請求的user_agent區別響應,可以配置,如無則使用默認配置
# 局部配置:對某個視圖類有效
# 在視圖類中先加入:
renderer_classes=[JSONRenderer,]
# 全局配置:對所有視圖類都有效
# 在settings.py中加入:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer']
}
# drf配置信息查找順序:先視圖類,后項目配置文件,最后默認配置
視圖
# 視圖基類:ModelViewSet(>GenericViewSet)>GenericAPIView>APIView>View
APIView
# 注冊rest_framework
# 在models.py中定義表模型
class Book(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=6,decimal_places=2)
author = models.CharField(max_length=32)
public = models.CharField(max_length=64)
# 在自定義文件中定義序列化器
from rest_framework import serializers
class BooksSerializer(serializers.Serializer):
name = serializers.CharField()
price = serializers.DecimalField(max_digits=6,decimal_places=2)
author = serializers.CharField()
public = serializers.CharField()
# 在views中定義視圖類
class BookView(APIView):
def get(self,request,id):
book = Book.objects.filter(id=id).first()
book_ser = BooksSerializer(book) # 參數就是要序列化的對象
# book_ser.data就是序列化后的字典
return Response(book_ser.data) # 也可以用JsonResponse返回,這樣不用注冊rest_framework,但不能通過判斷請求信息區別渲染
# 配置路由信息
GenericAPIView
class BookDetailView(GenericAPIView):
# queryset = Book.objects.all() # 查詢所有
# serializer_class = BookSerializer # 傳入自定義序列器
#
# 之后的內部視圖函數就可以使用self.get_queryset()、self.get_object()和self.get_serializer()方法,使用self.get_object(),需要路由配置中有名分組必須命名為pk,或者視圖類中配置lookup_url_kwarg屬性
# 這種方式是可以將查詢或者操作資源需要的query對象或者序列器封裝到self.中,在之后創建類似的其他表模型的視圖函數只需要復制視圖類,修改類名及類名中的queryset、serializer_class參數即可
# 但是這樣會造成代碼重復,所以可以引入已經寫好的5個類:
from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
class BookDetailView(GenericAPIView):
def get(self,request):
return self.list(request)
def post(self,request):
return self.create(request)
GenericAPIView的視圖子類9個
from rest_framework.generics import CreateAPIView,ListAPIView,DestroyAPIView,UpdateAPIView,RetrieveAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView,RetrieveUpdateDestroyAPIView # 繼承了GenericAPIView,基于基本5種組合而來
class Book(CreateAPIView,ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 以上即所有代碼
ModelViewSet(ReadOnlyModelViewSet)
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
# 繼承ModelViewSet創建視圖類,多個路由將指向同一個視圖類,這時需要指定.as_view()方法中的actions參數,實際上GenericViewSet繼承的ViewSetMixin類中重寫了.as_view()方法。
源碼
# ModelViewSet>GenericViewSet>ViewSetMixin>as_view>view
for method, action in actions.items():
handler = getattr(self, action)
setattr(self, method, handler)
# 循環解壓路由傳來的actions參數,并為視圖類對象的相應方法綁定已經寫好的方法的內存地址
ViewSetMixin使用
通過源碼,我們看到ViewSetMixin中重寫的as_view方法非常快樂,所以我們可以在繼承APIView、GenericAPIView創建視圖類時直接先繼承ViewSetMixin來借用
這樣可以多個路由指向我們同一個視圖類,并且手動配置請求方式和視圖類中函數的對應關系
視圖類匯總
兩個視圖基類:APIView、GenericAPIView
五個視圖拓展類(直接繼承object類):ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
九個視圖子類(繼承GenericAPIView和五個視圖拓展類中的一個或多個):CreateAPIView,ListAPIView,DestroyAPIView,UpdateAPIView,RetrieveAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView,RetrieveUpdateDestroyAPIView
五個視圖集:GenericViewSet、ModelViewSet、
ReadOnlyModelViewSet、ViewSet、ViewSetMixin
ModelViewSet:五個接口全
GenericViewSet:GenericAPIView+ViewSetMixin
ViewSet:APIView+ViewSetMixin
ViewSetMixin:重寫as_view()方法,可以在路由中用actions直接配置請求方式和視圖類中具體視圖函數的對應關系,手動配置或者使用Router自動配置,當視圖類中自定義了視圖函數時,可以在視圖函數前用@action裝飾器,action的參數有methods=[GET,POST]、detail=True,則生成的路由中配置了有名分組pk,需要'/1/get_2'類似的請求,且函數應添加形參pk
浙公網安備 33010602011771號