DRF的视图和路由
DRF视图
APIview
django中写CBV的时候是继承View,而rest_framework继承的是APIView,那么他们两个有什么不同
urlpatterns = [ url(r'^book$', BookView.as_view()), url(r'^book/(?P<id>\d+)$', BookEditView.as_view()), ]
不管是View还是APIView最开始调用的都是as_view()方法,看源码有什么区别
我们能看到,APIView继承了View, 并且执行了View中的as_view()方法,最后把view返回了,用csrf_exempt()方法包裹后去掉了csrf的认证。
然后看view中as_view()方法做了什么
在View中的as_view方法返回了view函数,而view函数执行了self.dispatch()方法 ,但是这里的dispatch方法按照顺序应该从自己开始寻找,而在APIview中,也写了dispatch方法,所以应该执行的是APIview中的dispatch方法
这里我我需要注意initialize_request中到底做了什么
这里返回的是一个实例化对象
这会django原先的request变成了self._request
视图
自己写的版本
# 自己重写的视图 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.viewsets import ViewSetMixin # 获取要的数据 class GenericAPIView(APIView): queryset = None serializer_class = None # 获取queryset def get_queryset(self): return self.queryset.all() # 获取序列化器 def get_serializer(self, *args, **kwargs): return self.serializer_class(*args, **kwargs) # get方法(查询多条) class ListModelMixin(object): def list(self, request): queryset = self.get_queryset() ser_obj = self.get_serializer(queryset, many=True) return Response(ser_obj.data) # 查询单条 class RetrieveModelMixin(object): def retrieve(self, request, id): stu_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(stu_obj) return Response(ser_obj.data) # post方法 class CreateModelMixin(object): def create(self, request): ser_obj = self.get_serializer(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) else: return Response(ser_obj.errors) # put/patch方法:修改单个的 class UpdateModelMixin(object): def update(self, request, id): stu_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(instance=stu_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) return Response(ser_obj.errors) # delete方法 class DestroyModelsMixin(object): def destroy(self, request, id): stu_obj = self.get_queryset().filter(id=id).first() if stu_obj: stu_obj.delete() return Response("") return Response("删除的对象不存在") # # 所有方法只要继承这个就可以 class ModelViewSet( ViewSetMixin, GenericAPIView, ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelsMixin, ): pass class Student(ModelViewSet): queryset = models.Student.objects serializer_class = StudentSerializer
他还有一个自带的模块和这个一样
from rest_framework.viewsets import ModelViewSet class Student(ModelViewSet): queryset = models.Student.objects serializer_class = StudentSerializer
urls.py代码
DRF的路由
这个路由其实也封装好了,但是封装越好的东西,应用场景限制的也越多
from .views import BookView from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r"book", BookView) urlpatterns = [ # url(r'^book$', BookView.as_view()), # url(r'^book/(?P<id>\d+)$', BookEditView.as_view()), # url(r'^book$', BookView.as_view({"get": "list", "post": "create"})), # url(r'^book/(?P<pk>\d+)$', BookView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})), ] urlpatterns += router.urls