水痕 2019-12-12
在我们有几十上百的视图类,都有get,post等方法,在功能类似时,会导致大量的重复代码出现,显然还有很多可以优化的地方。这也就有了视图组件,它的功能非常强大,能很好的优化接口逻辑。
# 1.导入mixins from rest_framework.mixins import ( ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin ) from rest_framework.generics import GenericAPIView from DrfOne import models # 2.定义序列化类 from DrfOne.drf_serializers import BookSerializer # 3.定义视图类 class BookView(ListModelMixin, CreateModelMixin, GenericAPIView): # 获取数据源, 固定写法 queryset = models.Book.objects.all() # 序列化类, 固定写法 serializer_class = BookSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) class BookFilterView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView): # 获取数据源, 固定写法 queryset = models.Book.objects.all() # 序列化类, 固定写法 serializer_class = BookSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
定义序列化类
from rest_framework import serializers from DrfOne import models class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = "__all__" extra_kwargs = { # 仅写 "publish": {‘write_only‘: True}, "authors": {‘write_only‘: True}, } publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name") publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address") author_name = serializers.SerializerMethodField() def get_author_name(self, book_obj): author_list = list() for author in book_obj.authors.all(): # 注意列表添加字段,author.name而不是author author_list.append(author.name) return author_list
注意:操作单条数据的 url
from django.urls import path, re_path from DrfOne import views urlpatterns = [ path(‘books/‘, views.BookView.as_view()), # 需要命名为pk re_path("books/(?P<pk>\d+)/", views.BookFilterView.as_view()), ]
通过上面代码发现 get , post 等方法内容相似,可以进行再次封装。
对 mixins 再次优化其余内容不变
# 1.导入generics from rest_framework import generics from DrfOne import models # 2.导入序列化类 from DrfOne.drf_serializers import BookSerializer # 3.定义视图类 class BookView(generics.ListCreateAPIView): # 获取数据源, 固定写法 queryset = models.Book.objects.all() # 序列化类, 固定写法 serializer_class = BookSerializer class BookFilterView(generics.RetrieveUpdateDestroyAPIView): queryset = models.Book.objects.all() serializer_class = BookSerializer
发现还是有重复代码,再次优化,也就是 viewset 。
看似已经优化的非常完美了,但是在一个对性能要求极高的项目里面,我们的程序还可以继续优化,不断的优化程序是每个程序员必备的技能。
注意urls.py的变化
from django.urls import path, re_path from DrfOne import views urlpatterns = [ # path(‘books/‘, views.BookView.as_view()), # re_path("books/(?P<pk>\d+)/", views.BookFilterView.as_view()), path("books/", views.BookView.as_view({ "get": "list", "post": "create", })), re_path(‘books/(?P<pk>\d+)/‘, views.BookView.as_view({ ‘get‘: ‘retrieve‘, ‘put‘: ‘update‘, ‘delete‘: ‘destroy‘ })), ]
views.py
# 2.导入viewset模块里的ModelViewSet类 from rest_framework.viewsets import ModelViewSet # 导入应用里的models from DrfOne import models # 3.导入序列化类 from DrfOne.drf_serializers import BookSerializer # 4.定义视图类 class BookView(ModelViewSet): # 获取数据源, 固定写法 queryset = models.Book.objects.all() # 序列化类, 固定写法 serializer_class = BookSerializer
~>.<~