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