视图和源码解析
通过使用mixin类编写视图:
from rest_framework import mixinsfrom rest_framework import genericsclass BookViewSet(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 BookDetailViewSet(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 import mixinsfrom rest_framework import genericsclass BookViewSet(generics.ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerializersclass BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerializersclass PublishViewSet(generics.ListCreateAPIView): queryset = Publish.objects.all() serializer_class = PublshSerializersclass PublishDetailViewSet(generics.RetrieveUpdateDestroyAPIView): queryset = Publish.objects.all() serializer_class = PublshSerializers
还有更简洁的写法:
views.py
class AuthorModelView(ModelViewSet): queryset=Author.objects.all() serializer_class=AuthorSerializers
urls.py
url(r'^authors/$', views.AuthorModelView.as_view({ "get":"list","post":"create"})), url(r'^authors/(?P\d+)/$', views.AuthorModelView.as_view({ "get":"retrieve","put":"update","delete":"destroy"})),
serializers.py
class AuthorSerializers(serializers.ModelSerializer): class Meta: model=Author fields="__all__"
那么来看看源码吧
serializers.ModelSerializer
以CreateModelMixin为例
再看看 GenericViewSet:
先看 ViewSetMixin ,其中定义了 as_view方法,因为该类在 generics.GenericAPIView之前定义,所以 cls.as_view 时会调用此方法:
看下 as_view 里的view 做了些什么,该类并没有定义 dispatch方法 :
再来看下 GenericAPIView 该类并没有 dispatch 方法,但是继承了 APIView,所以我们view会调用 APIView 的 dispatch方法
在 GenericAPIView 中你需要设置或覆盖的get_queryset() 、 get_serializer_class()。
如果你重写了一个视图方法,那么你应该调用'getqueryset()'而不是直接访问'queryset'属性,
因为对于所有后续的请求“queryset”只会被评估一次,并且会缓存这些结果
APIView这里就不多说了,上次写过了,看这个吧
再看看 mixins.UpdateModelMixin 吧,这个和删除,个查单个有共通之处,区别于list和create
这个 get_object()方法是在 GenericAPIView 里的
类继承关系