DRF框架基本组件之视图
REST framework 提供了一个 APIView 类,它继承于 Django 的 View 类。
1,APIView源码分析
#views.py from rest_framework.views import APIView class BookView(APIView): pass #------------------------------------------------ #urls.py url(r'^books/$', views.BookView.as_view()) #项目启动时找到类方法as_view并执行
#APIView部分源码 class APIView(View): @classmethod def as_view(cls, **initkwargs): #项目启动时最先在这找到类方法as_view,执行它返回view函数 view = super(APIView, cls).as_view(**initkwargs) # 此view函数继承自其父类View return csrf_exempt(view) #执行view函数时,self.dispatch(request, *args, **kwargs) 调用dispatch方法, #先从对象的类中找,再去其父类APIView中找,在这能找到dispatch方法,所以最终调用的 #是APIView类中的dispatch方法,而不再是View类中的dispatch方法! def dispatch(self, request, *args, **kwargs): if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response ---------------------
使用APIView 5种接口的实现:
url(r'^books/$', views.BookView.as_view()), url(r'^books/(\d+)/$', views.BookDetailView.as_view()),
from rest_framework.views import APIView from rest_framework.response import Response from .models import Book from .serializers import BookSerializer class BookView(APIView): def get(self, request): book_list = Book.objects.all() serializer = BookSerializer(book_list, many=True) return Response(serializer.data) def post(self, request): serializer = BookSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) class BookDetailView(APIView): def get(self, request, pk): book_obj = Book.objects.filter(pk=pk).first() serializer = BookSerializer(book_obj, many=False) return Response(serializer.data) def put(self, request, pk): book_obj = Book.objects.filter(pk=pk).first() serializer = BookSerializer(data=request.data, instance=book_obj) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) def delete(self, request, pk): Book.objects.filter(pk=pk).delete() return Response("ok")
2,GenericAPIView / mixin类
2.1 GenericAPIView 类继承于 REST framework 的 APIView 类,为标准列表和详细视图添加了常见的行为。
get_queryset(self) -->默认返回由 queryset 属性指定的查询集;
应该始终使用此方法, 而不是直接访问 self.queryset,因为 REST 会在内部对 self.queryset 的结果进行缓存用于后续所有请求。
get_serializer_class(self) -->返回用于序列化的类。默认返回 serializer_class 属性
2.2 mixin 类用于提供基本视图行为的操作
ListModelMixin -->提供一个 list(request, *args, **kwargs) 方法,实现了列出一个查询集;响应数据可以设置分页。
CreateModelMixin -->提供 create(request, *args, **kwargs) 方法,实现创建和保存新模型实例
RetrieveModelMixin -->提供 retrieve(request, *args, **kwargs) 方法,该方法实现在响应中返回现有的模型实例
UpdateModelMixin -->提供 update(request, *args, **kwargs) 方法,实现更新和保存现有模型实例。
还提供了一个 partial_update(request, *args, **kwargs) 方法,它与更新方法类似,只是更新的所有字段都是可选的。这允许支持 HTTP PATCH 请求。
DestroyModelMixin -->提供一个 destroy(request, *args, **kwargs) 方法,实现现有模型实例的删除
使用GenericAPIView与mixin 类 5种接口的实现:
#url url(r'^books/$', views.BookView.as_view()), url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()), #view from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin from rest_framework.generics import GenericAPIView class BookView(CreateModelMixin,ListModelMixin,GenericAPIView): queryset=Book.objects.all() serializer_class=BookSerializers def get(self,request): return self.list(request) def post(self,request): return self.create(request) class BookDetailView(DestroyModelMixin,UpdateModelMixin,RetrieveModelMixin,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)
2.3 内置通用视图类
class CreateAPIView(CreateModelMixin,GenericAPIView) -->仅用于创建实例;提供一个 post 请求的处理方法
class ListAPIView(ListModelMixin,GenericAPIView) -->仅用于读取模型实例列表。提供一个 get 请求的处理方法
class RetrieveAPIView(RetrieveModelMixin,GenericAPIView) -->仅用于查询单个模型实例。提供一个 get 请求的处理方法
class DestroyAPIView(DestroyModelMixin,GenericAPIView) -->仅用于删除单个模型实例;提供一个 delete 请求的处理方法
class UpdateAPIView(UpdateModelMixin,GenericAPIView) -->仅用于更新单个模型实例。提供 put 和 patch 请求的处理方法
ListCreateAPIView -->既可以获取实例集合,也可以创建实例列表;提供 get 和 post 请求的处理方法
RetrieveUpdateDestroyAPIView -->同时支持查询,更新,删除;提供 get,put,patch 和 delete 请求的处理方法
使用内置通用视图 5种接口的实现:
#url url(r'^books/$', views.BookView.as_view()), url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()), #view from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView class BookView(ListCreateAPIView): queryset=Book.objects.all serializer_class=BookSerializers class BookDetailView(RetrieveUpdateDestroyAPIView): queryset = Book.objects.all serializer_class = BookSerializers
3, 视图集 ViewSet
Django REST framework 允许将一组相关视图的逻辑组合到一个称为 ViewSet 的类中。
ModelViewSet 类继承自 GenericAPIView,并通过混合各种 mixin 类的行为来包含各种操作的实现。
使用ModelViewSet 类 5种接口的实现:
url(r'^books/$', views.BookModelView.as_view({'get':'list','post':'create'})), url(r'^books/(?P<pk>\d+)/$', views.BookModelView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
from rest_framework.viewsets import ModelViewSet
class BookModelView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
使用路由器
现在我们使用的是
ViewSet
类而不是View
类,那么就不需要自己设计URL路由,通过使用Router
类,把视图和资源联系起来的协议和urls会被自动处理。我们只需要使用router来注册合适的视图,剩余的交给router来做就行。
from django.conf.urls import url, include from rest_framework.routers import DefaultRouter from snippets import views # 实例化一个 router 并用它注册我们的 viewsets router = DefaultRouter() router.register(r'snippets', views.SnippetViewSet,basename='snippets') router.register(r'users', views.UserViewSet , basename='users')
# API URLs 现在由 router 自动配置. urlpatterns = [ url(r'^', include(router.urls)) ]
register()函数有两个必要参数:
prefix: 字首,用来表示一系列的urls
viewset: viewset class
可选的参数:
base_name: 用来生成urls名字,如果viewset中没有包含queryset, base_name一定要有