一、mixins类编写视图
1、配置url
urlpatterns = [ ... re_path(r'^authors/$', views.AuthorView.as_view(), name="author"), re_path(r'^authors/(?P<pk>\d+)/$', views.AuthorDetailView.as_view(), name="detail_author") ]
2、编写Author的序列化类
/app01/serializer.py:
class AuthorModelSerializers(serializers.ModelSerializer): class Meta: model = Author fields = "__all__"
3、编写Author的视图
# Author from rest_framework import mixins, generics class AuthorView(mixins.ListModelMixin, # 扩展了列出查询集功能 mixins.CreateModelMixin, # 扩展了创建和保存新模型实例功能 generics.GenericAPIView): # 继承扩展了REST框架的APIView类,为标准列表和详细视图添加了常见的行为 queryset = Author.objects.all() # 配置queryset:告知这个类这次处理的数据 serializer_class = AuthorModelSerializers # 告知处理用到的序列化组件 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 AuthorDetailView(mixins.RetrieveModelMixin, # 扩展在响应中实现返回现有模型实例功能(获取单条数据) mixins.DestroyModelMixin, # 扩展现有模型实例的删除功能 mixins.UpdateModelMixin, # 扩展更新和保存现有模型实例功能 generics.GenericAPIView): queryset = Author.objects.all() # 配置queryset:告知这个类这次处理的数据 serializer_class = AuthorModelSerializers # 告知处理用到的序列化组件 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)
注意:
(1)queryset和serializer_class变量
这两个变量是必须的。queryset告知这个类这次处理的数据。serializer_class告知这个类数据处理用到的序列化组件。
(2)五类mixins作用和对应的http方法
(3)GenericAPIView
这个类扩展了REST框架的APIView
类,为标准列表和详细视图添加了常见的行为。
提供的每个具体的通用视图都是通过把GenericAPIView
与一个或多个mixin类进行组合来构建的。
(4)测试验证
二、Mixins源码分析
1、CreateModelMixin
class CreateModelMixin(object): """Create a model instance ==>创建一个实例""" def create(self, request, *args, **kwargs): # 获取相关serializer serializer = self.get_serializer(data=request.data) # 进行serializer的验证;raise_exception=True,一旦验证不通过,不再往下执行,直接引发异常 serializer.is_valid(raise_exception=True) # 调用perform_create()方法,保存实例 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 {}
注意:
(1)perform_create( )对serializer直接进行save保存,当在一些情境下,需要对perform_create( )进行重写。
(2)这个类的运行流程如下所示:
2、ListModelMixin
class ListModelMixin(object): """List a queryset.==> 列表页获取""" def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) # 这是一个分页功能,如果在viewset中设置了pagination_class,那么这里就会起作用 # 获取当前页的queryset,如果不存在分页,返回None page = self.paginate_queryset(queryset) if page is not None: # 分页不为空,那么不能简单的执行Response(serializer.data) # 还需要将相关的page信息序列化在进行响应 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)
ListModelMixin一般用来获取列表页,不需要重写方法。
3、RetriveModelMixin
class RetrieveModelMixin(object): """ Retrieve a model instance.==> 获取某一个对象的具体信息 """ def retrieve(self, request, *args, **kwargs): # 一般访问的url都为/obj/id/这种新式 # get_object()可以获取到这个id的对象 # 注意在viewset中设置lookup_field获取重写get_object()方法可以指定id具体对象是什么~! instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data)
4、DestoryModelMixin
class DestroyModelMixin(object): """ 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()
5、总结
这一章简要分析了源码的内容以及各个mixins的逻辑,最重要的还是学会重写它们相关的方法。一般情况下,当我们在操作某一个model的时候,涉及到另外一个model中数据的修改,那么就需要对这个mixins下执行save的逻辑的方法进行重写。