1. 程式人生 > >GenericAPIView類與幾個擴充套件類的綜合使用

GenericAPIView類與幾個擴充套件類的綜合使用

  • 五個擴充套件類

擴充套件類 作用 封裝的方法 狀態碼(成功,失敗)
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()