drf interface-Written by myself, inherit APIView and write books with 5 interfaces, inherit APIView, have two class attributes, extend classes based on 5 views, and write interfaces and view sets through 9 view subclasses

1. The first layer, written by ourselves, inherits APIView and writes 5 interfaces for books

1.Routing
path('books/', BookView.as_view()),
    path('books/<int:pk>/', BookDetailView.as_view()),
    
path('publish/', PublishView.as_view()),
    path('publish/<int:pk>/', PublishDetailView.as_view()),

2.serializer class
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=Publish
        fields = '__all__'

3. View function
class BookView(APIView):
    def get(self, request):
        book = Book.objects.all()
        ser = BookSerializer(instance=book, many=True)
        # ser.data is serialized
        return Response({<!-- -->'code': 200, 'msg': 'Query successful', 'data': ser.data})

    def post(self, request):
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({<!-- -->'code': 200, 'msg': 'Added successfully', 'data': ser.data})
        return Response({<!-- -->'code': 201, 'msg': 'Query failed', 'data': ser.errors})


class BookDetailView(APIView):
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book)
        return Response({<!-- -->'code': 200, 'msg': 'Query successful', 'data': ser.data})

    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({<!-- -->'code': 200, 'msg': 'Modification successful', 'data': ser.data})
        return Response({<!-- -->'code': 201, 'msg': 'Modification failed', 'data': ser.errors})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response('')


from .serializer import PublishSerializer
from .models import Publish


class PublishView(APIView):
    def get(self, request):
        obj_list = Publish.objects.all()
        ser = BookSerializer(instance=obj_list, many=True)
        # ser.data is serialized
        return Response({<!-- -->'code': 200, 'msg': 'Query successful', 'data': ser.data})

    def post(self, request):
        ser = PublishSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({<!-- -->'code': 200, 'msg': 'Added successfully', 'data': ser.data})
        return Response({<!-- -->'code': 201, 'msg': 'Query failed', 'data': ser.errors})


class PublishDetailView(APIView):
    def get(self, request, pk):
        obj = Publish.objects.filter(pk=pk).first()
        ser = PublishSerializer(instance=obj)
        return Response({<!-- -->'code': 200, 'msg': 'Query successful', 'data': ser.data})

    def put(self, request, pk):
        book = Publish.objects.filter(pk=pk).first()
        ser = PublishSerializer(instance=book, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({<!-- -->'code': 200, 'msg': 'Modification successful', 'data': ser.data})
        return Response({<!-- -->'code': 201, 'msg': 'Modification failed', 'data': ser.errors})

    def delete(self, request, pk):
        Publish.objects.filter(pk=pk).delete()
        return Response('')

2. The second layer inherits APIView and has two class attributes

1.Routing
path('publish/', PublishView.as_view()),
    path('publish/<int:pk>/', PublishDetailView.as_view()),

2.serializer class
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=Publish
        fields = '__all__'

3. View function
class GenericAPIView(APIView):
    queryset = None
    serializer_class = None

    def get_queryset(self):
        return self.queryset.all() # When actually using it, add all to get all

    def get_serializer(self, *args, **kwargs):
        return self.serializer_class(*args, **kwargs)

    def get_object(self, pk):
        return self.get_queryset().filter(pk=pk).first()


#### Provided by drf
from rest_framework.generics import GenericAPIView


class PublishView(GenericAPIView):
    queryset = Publish.objects.all() # The class will be executed as long as it is loaded.
    serializer_class = PublishSerializer

    def get(self, request):
        obj_list = self.get_queryset()
        ser = self.get_serializer(instance=obj_list, many=True)
        # ser.data is serialized
        return Response({<!-- -->'code': 200, 'msg': 'Query successful', 'data': ser.data})

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({<!-- -->'code': 200, 'msg': 'Added successfully', 'data': ser.data})
        return Response({<!-- -->'code': 201, 'msg': 'Query failed', 'data': ser.errors})


class PublishDetailView(GenericAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    # Generally it is not recommended to write like this, just use GenericAPIView.
    # lookup_field = 'id'

    def get(self, request, pk):
        # We wrote it ourselves
        # obj = self.get_object(pk=pk)
        # The one provided by drf does not need to be passed in pk.
        obj = self.get_object()
        ser = self.get_serializer(instance=obj)
        return Response({<!-- -->'code': 200, 'msg': 'Query successful', 'data': ser.data})

    # def get_serializer_class(self):
    # if self.request.method == 'get':
    # return self.serializer_class
    #else:
    # return 'Writing a serialization myself'

    def put(self, request, pk):
        # We wrote it ourselves
        # obj = self.get_object(pk=pk)
        # Provided by drf, no need to pass in pk.
        obj = self.get_object()
        ser = self.get_serializer(instance=obj, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({<!-- -->'code': 200, 'msg': 'Modification successful', 'data': ser.data})
        return Response({<!-- -->'code': 201, 'msg': 'Modification failed', 'data': ser.errors})

    def delete(self, request, pk):
        # We wrote it ourselves
        # self.get_queryset().filter(pk=pk).delete()
        # drf comes with
        self.get_object().delete()
        return Response('')

3. The third layer extends classes based on 5 views

1.Routing
path('publish/', PublishView.as_view()),
    path('publish/<int:pk>/', PublishDetailView.as_view()),

2.serializer class
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=Publish
        fields = '__all__'

3. View function
from rest_framework.mixins import RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, ListModelMixin, \
    UpdateModelMixin
# RetrieveModelMixin, query a
# CreateModelMixin, new
# DestroyModelMixin, delete
# ListModelMixin, query all
# UpdateModelMixin, modify

from rest_framework.generics import GenericAPIView
from .models import Publish
from .serializer import PublishSerializer


class PublishView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Publish.objects.all() # The class will be executed as long as it is loaded.
    serializer_class = PublishSerializer

    def get(self, request):
        return self.list(request=request)

    def post(self, request):
        # Don't forget to return, you can also use super
        # return self.create(request=request)
        return super().create(request=request)


class PublishDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request, pk):
        return self.retrieve(request=request, pk=pk)

    def put(self, request, pk):
        return self.update(request=request, pk=pk)

    def delete(self, request, pk):
        return self.destroy(request=request, pk=pk)

4. The fourth layer, writing interfaces through 9 view subclasses

1.Routing
path('publish/', PublishView.as_view()),
    path('publish/<int:pk>/', PublishDetailView.as_view()),

2.serializer class
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=Publish
        fields = '__all__'

3. View function
from rest_framework.generics import ListAPIView, CreateAPIView, ListCreateAPIView

from .models import Publish
from .serializer import PublishSerializer

# 1. GenericAPIView + ListModelMixin = ListAPIView

# class ListAPIView(GenericAPIView, ListModelMixin):
# def get(self, request):
# return self.list(request)

# 2. GenericAPIView + CreateModelMixin = CreateAPIView

# 3. GenericAPIView + ListModelMixin + CreateModelMixin = ListCreateAPIView

from rest_framework.generics import RetrieveAPIView, DestroyAPIView, UpdateAPIView
from rest_framework.generics import RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView


# Want to write publish: query all: query a single item, modify an item, add an item, delete an item interface
class PublishView(ListCreateAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer


class PublishDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer


# Want to write publish: Query all: query a single item, modify an item, add an item, delete an item ----> Use 5 view extension classes + GenericAPIView to write res
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, \
    DestroyModelMixin, RetrieveModelMixin, ListModelMixin


class PublishView(GenericAPIView, CreateModelMixin):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    # *args in post receives positional parameters of any length and **kwargs receives keyword parameters.
    def post(self, request, *args, **kwargs):
        # *args in create is a broken list and is passed in. **kwargs is a dictionary that is broken up and passed in.
        return self.create(request, *args, **kwargs)


class PublishDetailView(GenericAPIView, RetrieveModelMixin):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)


5. The fifth layer, view set

1.Routing
path('publish/', PublishView.as_view(actions={<!-- -->'get': 'list', 'post': 'create'})),
    path('publish/<int:pk>/', PublishView.as_view(actions={<!-- -->'get': 'retrieve', 'put': 'update ', 'delete': 'destroy'})),

2.serializer class
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=Publish
        fields = '__all__'

3. View function
from rest_framework.viewsets import ModelViewSet
from .models import Publish
from .serializer import PublishSerializer


class PublishView(ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer