CreateAPIView, ListAPIView, RetrieveAPIView, DestroyAPIView UpdateAPIView重构方法

ListAPIView

'''
重构list方法,

def list(self, request, *args, **kwargs):
    response = super().list(request, *args, **kwargs)
    
response 父类list方法的返回值Response(serializer.data),即序列化后的数据serializer.data

response.data = context 给response添加键值对

return response 再将新的response返回给前端
'''

父类list方法

class ListModelMixin:
    """
    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)

重构list方法

class BidView(ListAPIView, CreateAPIView):

    authentication_classes = [UserAuthentication, ]
    permission_classes = [BidPermission, ]
    queryset = models.BidRecord.objects.all().order_by('-id')
    serializer_class = BidModelSerializer
    filter_backends = [BidItemFilter, ]

    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        if response.status_code != status.HTTP_200_OK:
            return response
        lot_id = request.query_params.get('lot_id')
        lot_object = models.Lot.objects.filter(id=lot_id).first()

        context = {
            'unit': lot_object.unit,
            'price': response.data[0]['price'] if response.data else lot_object.start_price,
            'bid_list': response.data
        }
        response.data = context
        return response

CreateAPIView

'''
重构perform_create方法

前端数据校验成功后,执行perform_create(self, serializer)方法保存数据到数据库

'''

父类list方法

class CreateModelMixin:
    """
    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 {}

重构perform_create方法

class BidView(ListAPIView, CreateAPIView):

    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user.id, status=1)

RetrieveAPIView

'''
重构get方法/retrieve方法

def get(self, request, *args, **kwargs):
    # 1. 获取详细信息
    response = self.retrieve(request, *args, **kwargs)

同ListAPIView相似

'''

父类方法

class RetrieveAPIView(mixins.RetrieveModelMixin,
                  GenericAPIView):
    """
    Concrete view for retrieving a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)


class RetrieveModelMixin:
    """
    Retrieve a model instance.
    """
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

重构get方法/retrieve方法

class NewsDetailView(RetrieveAPIView):
    """
    获取动态详细接口
    """
    queryset = models.News.objects
    serializer_class = RetrieveNewsDetailModelSerializerSerializer

    def get(self, request, *args, **kwargs):
        # 1. 获取详细信息
        response = self.retrieve(request, *args, **kwargs)

        # 2. 处理用户浏览记录,当前用户添加到记录中
        #    2.1 用户未登录,不记录
        #    2.2 用户登录,已记录则不再记录记录,未记录则添加到浏览记录中。
        if not request.user:
            return response
        news_object = self.get_object()
        if not news_object:
            return response

        viewer_queryset = models.ViewerRecord.objects.filter(news=news_object, user_id=request.user.id)
        if not viewer_queryset.exists():
            models.ViewerRecord.objects.create(news=news_object, user_id=request.user.id)
            models.News.objects.filter(id=news_object.id).update(favor_count=F("viewer_count") + 1)

        return response

DestroyAPIView

'''
啦啦啦,没用过。。。,用过补充

'''

父类方法

class DestroyModelMixin:
    """
    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()

UpdateAPIView

'''
啦啦啦,没用过。。。,用过补充

'''

父类方法

class UpdateAPIView(mixins.UpdateModelMixin,
                    GenericAPIView):
    """
    Concrete view for updating a model instance.
    """
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def patch(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)


class UpdateModelMixin:
    """
    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)
希望你眼眸有星辰,心中有山海,从此以梦为马,不负韶华
原文地址:https://www.cnblogs.com/daviddd/p/12410783.html