GenericAPIView類與幾個擴充套件類的綜合使用
阿新 • • 發佈:2018-11-11
-
五個擴充套件類
擴充套件類 | 作用 | 封裝的方法 | 狀態碼(成功,失敗) |
---|---|---|---|
ListModelMixin | 查詢多條資料 | list | 200 |
CreateModelMixin | 新增一條資料 | create | 201,400 |
RetrieveModelMixin | 查詢一條資料 | retrieve | 200,404 |
UpdateModelMixin | 更新一條資料 | update,partial_update |
200,400 |
DestroyModelMixin | 刪除一條資料 | destroy | 204,404 |
這五個擴充套件類需要搭配GenericAPIView (或者GenericViewSet)一起使用:五個擴充套件類的需要呼叫GenericAPIView提供的序列化器與資料庫查詢的方法。
-
使用方法
class DepartmentListAPIView(ListModelMixin,CreateModelMixin,GenericAPIView): queryset = Department.objects.all() serializer_class= DepartmentSerializer def get(self,request): """查詢多條資料""" return self.list(request) def post(self,request): """新增一條資料""" return self.create(request) class DepartmentDetailAPIView(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView): queryset= Department.objects.all() serializer_class = DepartmentSerializer def get(self,request,pk): """查詢一條資料""" return self.retrieve(request,pk) def post(self,request,pk): """修改部門""" return self.update(request,pk) def delete(self,request,pk): """刪除一個部門""" return self.destroy(request,pk)
-
五個擴充套件類的原始碼
""" Basic building blocks for generic class based views. We don't bind behaviour to http method handlers yet, which allows mixin classes to be composed in interesting ways. """ from __future__ import unicode_literals from rest_framework import status from rest_framework.response import Response from rest_framework.settings import api_settings class CreateModelMixin(object): """ Create a model instance. """ def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def perform_create(self, serializer): serializer.save() def get_success_headers(self, data): try: return {'Location': str(data[api_settings.URL_FIELD_NAME])} except (TypeError, KeyError): return {} class ListModelMixin(object): """ List a queryset. """ def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) class RetrieveModelMixin(object): """ Retrieve a model instance. """ def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data) class UpdateModelMixin(object): """ Update a model instance. """ def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} return Response(serializer.data) def perform_update(self, serializer): serializer.save() def partial_update(self, request, *args, **kwargs): kwargs['partial'] = True return self.update(request, *args, **kwargs) class DestroyModelMixin(object): """ Destroy a model instance. """ def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) def perform_destroy(self, instance): instance.delete()