day93-view package & routing component & version control

day93-view package & routing component & version control

1. The first package and the second package of the view

1. The first package and the second package (the second package is just to integrate inherited classes)

1.1 First of all, clearly encapsulate, because the difference between different additions, deletions, and changes lies in the different tables and different serializers.

Tables and serialization classes can be written in a class method

1.2 A single query is different from multiple queries, write separately

1.3 So the strategy is:

- First write a base class, define empty queryset and serializers to be rewritten after inheritance,

- Write a single class and then write a separate class

1.4 Pay attention to adding the .all() method when returning the queryset

1.5 Pay attention to setting the parameters *args, **kwargs when returning the serialization function

1.6 Naming Convention

--GenericAPIView is used to be rewritten by inheritance, keyword Generic

--XxxModelMixin independent inheritance meaningless, keyword ModelMixin

from rest_framework.viewsets import ViewSetMixin

from DjangoDemo.models import Book
from rest_framework.views import APIView, Response
from SerDemo.serializers import BookSerializer
from rest_framework import views

"""""""""""""""Global First & 2.Encapsulation"""""""""""""""


class GenericAPIView(APIView):
    """
    Generic
    First package
    step1: The parent class parameters are different, defined as None, let the subclass rewrite
    """
    queryset = None
    serializers_class = None

    # Custom function returns queryset
    def get_queryset(self):
        return self.queryset.all() # django's pit

    # Custom function returns serialization class
    def get_serializers(self, *args, **kwargs):
        return self.serializers_class(*args, **kwargs)


# Display logic
class ListModelMixin(GenericAPIView): # Mixin
    def list(self, request):
        queryset = self.get_queryset()
        ser_obj = self.get_serializers(queryset, many=True)
        return Response(ser_obj.data)


# Create logic
class CreateModelMixin(GenericAPIView):
    def create(self, request):
        ser_obj = self.get_serializers(data=request.data)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ser_obj.validated_data)
        else:
            return Response(ser_obj.errors)


# The second encapsulation is just to facilitate inheritance
class ListCreateAPIView(ListModelMixin, CreateModelMixin):
    pass


# Search for a certain batch of books & create new books
class BookView(ListCreateAPIView):
    """
    step2: Inherit the class and rewrite the parameters
    The child class will use all the methods of the parent class
    """
    queryset = Book.objects.all()
    serializers_class = BookSerializer

    # def get(self, request):
    # # Call the external get method
    # book_queryset = Book.objects.all()
    # # Serialize with serializer
    # ser_obj = BookSerializer(book_queryset, many=True)
    # return Response(ser_obj.data)

    # Increase the view of the book
    # postVerify the verification of deserialization
    # Note save
    def get(self, request):
        return self.list(request)

    # def post(self, request):
    # # The data passed by the interface is in request.data
    # # Use serializer to verify the amount of post parameters
    # ser_obj = BookSerializer(data=request.data)
    # if ser_obj.is_valid():
    # ser_obj.save()
    # return Response(ser_obj.validated_data)
    # else:
    # return Response(ser_obj.errors)
    def post(self, request):
        return self.create(request)


"""""""""""""""Multiple & single dividing line""""""""""""""""


# View single category
class RetrieveModelMixin(GenericAPIView):
    def retrieve(self, request, pk):
        book_obj = self.get_queryset().filter(id=pk).first()
        ser_obj = self.get_serializers(book_obj)
        return Response(ser_obj.data)


# Update a single category
class UpdateModelMixin(GenericAPIView):
    def update(self, request, pk):
        book_obj = self.get_queryset().filter(id=pk).first()
        ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response('The data after verification is -->()'.format(ser_obj.validated_data))
        return Response('Verification failed, failure message-->{}'.format(ser_obj.errors))


# Delete a single category
class DestroyModelMixin(GenericAPIView):
    def destroy(self, request, pk):
        book_obj = self.get_queryset().filter(id=pk).first()
        if not book_obj:
            return Response('Delete book does not exist')
        book_obj.delete()
        return Response('Book deleted successfully!')


# The second encapsulation is just to facilitate inheritance
class RetrieveUpdateDestroyAPIView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    pass


# Query and edit a piece of data
class BookEditView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Book.objects.all()
    serializers_class = BookSerializer

    # def get(self, request, obj_id):
    # book_obj = Book.objects.filter(id=obj_id).first()
    # ser_obj = BookSerializer(book_obj)
    # return Response(ser_obj.data)
    def get(self, request, pk):
        return self.retrieve(request, pk)

    # def put(self, request, obj_id):
    # book_obj = Book.objects.filter(id=obj_id).first()
    # "put request for editing"
    # "instance object, data data, partial parameter"
    # ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
    # if ser_obj.is_valid():
    # ser_obj.save()
    # return Response('The data after verification is -->()'.format(ser_obj.validated_data))
    # return Response('Verification failed, failure message-->{}'.format(ser_obj.errors))
    def put(self, request, pk):
        return self.update(request, pk)

    # def delete(self, request, obj_id):
    # book_obj = Book.objects.filter(id=obj_id).first()
    # if not book_obj:
    # return Response('Delete book does not exist')
    # book_obj.delete()
    # return Response('Book deleted successfully!')
    def delete(self, request, pk):
        return self.destroy(request, pk)

2. The third package (connected to the code above), usually the second layer of packaging is used, and the third layer of packaging is basically not used

2.1 The third layer is encapsulated in the view

2.1.1 Write a class to inherit all secondary encapsulation classes

2.1.2 Inherit another ViewSetMixin class, from rest_framework.viewsets import ViewSetMixin

2.1.3 Write a class that inherits this three-time encapsulated class, and also configure queryset and serializer_class

""""""""""""""""Global third encapsulation"""""""""""""""""


# Inherit ViewSetMixin (from rest_framework.viewsets import ViewSetMixin) and the pass class inherited only for the second time above
class ModelViewSet(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView):
    pass


# Encapsulate the global APIView for the third time
class BookModelView(ModelViewSet):
    # Also configure queryset and serializer_class
    queryset = Book.objects.all()
    serializers_class = BookSerializer

2.2 The package class is configured to pass parameters in the url (note that id is replaced by pk, do not use id)

2.2.1 Bring the third encapsulated BookModelView written in views. 2.2.2 Big pit! id all use pk instead of 2.2.3 parameter accepts a dictionary, the key value is the request method: the function name of the processing logic

"""Take the third encapsulated BookModelView written in views"""
"""Dakeng! Id all use pk instead of """
The """ parameter accepts a dictionary, and the key value is the request method: the function name of the processing logic """
urlpatterns = [
    url(r'book/$', views.BookModelView.as_view({"get": "list", "post": "create"})),
    url(r'book/(?P<pk>\d+)', views.BookModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})) ,
]

2. Routing component (used in url, not very much used)

# Help us generate routing with parameters
from rest_framework.routers import DefaultRouter
# Instantiate the DefaultRouter object
router = DefaultRouter()
# Register our route and view
router.register(r'^book', views.BookModelView)
# urlpatterns += router.urls

3. Version control

3.1 Version control is to determine the version number before the request reaches the view, which is convenient for the view to make logical judgments

class MyVersion(object):
    @staticmethod
    # Fixed function name, to control the version before the request reaches the view
    def determine_version(request, *args, **kwargs):
        # The return value of the method is the version number
        # Get the version number passed by the front end and return the version number
        version = request.query_params.get("version")
        if not version:
            version = "v1"
        return version

3.2 settings configuration information

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [],
    # Configure version control
    "DEFAULT_VERSIONING_CLASS": "utils.version.MyVersion",
    # Default version
    'DEFAULT_VERSION': None,
    # Allowed version
    'ALLOWED_VERSIONS': None,
    'VERSION_PARAM':'version'
}

3.3 Print version information in the view

# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView


class VersionDemo(APIView):
    # Here you can also request a configuration version for a single view
    # versioning_class = MyVersion
    def get(self, request):
        print('Current version-->', request.version)
        # scheme The instantiated object of the version control class I configured
        print(request.versioning_scheme)
        return Response('version control interface')

3.4 Other ways of passing version parameters

# Enter versioning
from rest_framework import versioning
Reference: https://cloud.tencent.com/developer/article/1594918 day93-view package & routing component & version control-cloud + community-Tencent Cloud