试图集ViewSet
介绍ViewSet
- list() 提供一组数据
- retrieve() 提供单个数据
- create() 创建数据
- update() 保存数据
- destory() 删除数据
ViewSet视图集不再实现get(),post()等方法,而是实现动作action如list(),create()等。视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。
视图集存在的意义:
- 将所有的接口可以写在一个类试图中(类试图中的方法不再用请求方法名小写 行为/动作 list/create)
- 重写了as_view({‘get’:‘list’, ‘post’:‘create’})
使用ViewSet开发api案例
1.views.py
'''使用试图集的ViewSet开发api'''
class BookViewSet(ViewSet):
def list(self, request):
qs = BookInfo.objects.all()
serializer = BookInfoModelSerializer(instance=qs, many=True)
return Response(serializer.data)
def retrieve(self, request, pk):
try:
book = BookInfo.objects.get(id=pk)
except BookInfo.DoesNotExist:
Response(status=status.HTTP_404_NOT_FOUND)
serializer = BookInfoModelSerializer(instance=book)
return Response(serializer.data)
2.urls.py
from django.conf.urls import url
from . import views
# 视图集路由
url(r'^books/$', views.BookViewSet.as_view({'get':'list'})),
url(r'^books/(?P<pk>\d+)$', views.BookViewSet.as_view({'get':'retrieve'}))
使用使用GenericViewSet + Mixin开发api案例
1.views.py
from booktest.models import BookInfo,HeroInfo
from .serializers import BookInfoModelSerializer,HeroInfoModelSerializer
from rest_framework.mixins import ListModelMixin,CreateModelMixin,DestroyModelMixin,UpdateModelMixin,RetrieveModelMixin
from rest_framework.viewsets import ViewSet,GenericViewSet,ReadOnlyModelViewSet,ModelViewSet
'''使用GenericViewSet + Mixin开发api'''
class BookViewSet( DestroyModelMixin, CreateModelMixin, UpdateModelMixin, ReadOnlyModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
附加viewsset的部分源码,其实ReadOnlyModelViewSet 包含了 GenericViewSet 与 ListModelMixin 与 RetrieveModelMixin
class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
pass
- urls.py
from django.conf.urls import url
from . import views
# 视图集路由
url(r'^books/$', views.BookViewSet.as_view({'get':'list', 'post': 'retrieve'})),
url(r'^books/(?P<pk>\d+)$', views.BookViewSet.as_view({'get':'retrieve', 'delete':'destroy', 'put':'update'}))
最牛逼的一种开发api方式(使用ModelViewSet + 自动注册路由)
- views.py
'''最叼继承 ModelViewSet'''
class BookViewSet( ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
- urls.py
from rest_framework.routers import DefaultRouter
urlpatterns = [
]
router = DefaultRouter() # 创建路由器
router.register(r'book', views.BookViewSet) #注册路由
urlpatterns += router.urls
自定义视图(自己定义的逻辑)
1.views.py
@action(methods=[指定下面的行为接受什么请求], detail=是不是详情视图,详情视图为True,生成路由books/pk/latest,列表视图为False,生成路由books/latest)
from booktest.models import BookInfo,HeroInfo
from .serializers import BookInfoModelSerializer,HeroInfoModelSerializer
from rest_framework.viewsets import ViewSet,GenericViewSet,ReadOnlyModelViewSet,ModelViewSet
# 用于urls.py自动创建自定义视图的路由
from rest_framework.decorators import action
class BookViewSet( ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
@action(methods=['get'], detail=False)
def latest(self, request):
book = BookInfo.objects.latest('id')
serializer = self.get_serializer(book)
return Response(serializer.data)
@action(methods=['put'], detail=True)
def read(self, request, pk):
'''修改图书的数量'''
book = self.get_object()
book.bread = request.data.get('bread')
book.save()
serializer = self.get_serializer(book)
return Response(serializer.data)
2.urls.py
创建路由器(!!!路由器只可以结合试图集一块用!!!)默认只生成标准的增删改查,如果想生成自定义的路由需要在views.py的自定义视图上添加装饰器action(from rest_framework.decorators import action)
!!!路由器只可以结合试图集一块用!!!
!!!路由器只可以结合试图集一块用!!!
!!!路由器只可以结合试图集一块用!!!
from rest_framework.routers import DefaultRouter,SimpleRouter
urlpatterns = [
]
router = DefaultRouter() # 创建路由器
router.register(r'book', views.BookViewSet, base_name='bookinfo') #注册路由
urlpatterns += router.urls
DefaultRouter与SimpleRouter的区别: DefaultRouter可以自动生成根视图不报错
谢谢观看~