RESTframwork之视图view
一 在view.py 中:
class AuthorView(APIView): def get(self, request): author_list = Author.objects.all() # 方式1: Django的序列化组件 # ret=serialize("json",publish_list) # 方式2:rest的序列化 As = AuthorSerializers(author_list, many=True) # 序列化数据 return Response(As.data) def post(self, request): # 添加一条数据 print(request.data) As = AuthorSerializers(data=request.data) if As.is_valid(): As.save() # 生成记录 return Response(As.data) else: return Response(As.errors) class AuthorDetailView(APIView): def get(self, request, pk): author_obj = Author.objects.filter(pk=pk).first() As = AuthorSerializers(author_obj, many=False) return Response(As.data) def put(self, request, pk): author_obj = Author.objects.filter(pk=pk).first() print(request.data,author_obj) # 结果为:{'name': '莫言1', 'age': 88, 'authorDetail': 2} 周围 As = AuthorSerializers(data=request.data, instance=author_obj) if As.is_valid(): As.save() # update return Response(As.data) else: return Response(As.errors) def delete(self, request, pk): Author.objects.filter(pk=pk).delete() return Response("")
mixin类编写视图:
初步封装方法:如果按照这种方式,我们每个类都需要重复写大量的代码:所以为了解决这个问题,我们对类进行封装。
from rest_framework import mixins from rest_framework import generics class BookView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers 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 BookDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers 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)
进一步封装:
通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py
模块。
from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin
from rest_framework import generics
class AuthorView(generics.ListCreateAPIView):
'''
因为ListCreateAPIView继承了:
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView)
'''
queryset=Author.objects.all
serializer_class=AuthorSerializers
class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
'''
因为继承了:class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView)
'''
queryset = Author.objects.all
serializer_class = AuthorSerializers
终极封装:
from rest_framework.viewsets import ModelViewSet ''' 我们可以看下ModelViewSet中源码的解释: class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): """ A viewset that provides default `create()`, `retrieve()`, `update()`, `partial_update()`, `destroy()` and `list()` actions. """ 提供了create()`, `retrieve()`, `update()`, `partial_update()`, `destroy()` and `list()` 这样六种方法。 ''' class AuthorModelView(ModelViewSet): queryset=Author.objects.all() serializer_class=AuthorSerializers
关于终极封装我们需要知道:
我们首先看url中传入的参数,这个时候我们为了区分两种GET请求,那么我们需要在as_view()中传值,初始化的时候就会执行as_view()方法,返回一个view方法。
当请求来的时候会执行view函数,执行到dispatch的时候发现执行不下去了,这个时候我们只能去APIView中去找到我们的dispatch方法。那么这里为什么去APIView中去执行
dispatch方法呢:
APIView(View)
GenericAPIView(views.APIView) 这个类中没有dispatch方法。
ViewSet(ViewSetMixin, views.APIView):
那么我们整个ViewSet最关键的就是这么三行代码:
for method, action in actions.items(): handler = getattr(self, action) setattr(self, method, handler)
执行完这三行代码,我们的GET对应的方法就变成了list,POST变成CREATE方法。