一、ModelViewSet继承的是GenericViewSet,和五个拓展类,所以它的写法如下:
class Books(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookSerializer
路由匹配:
url(r'^book_drf/$', modelviewset_view.Books.as_view({'get': 'list', 'post': 'create'})), url(r'^book_drf/(?P
from django.urls import path
from django.conf.urls import url
from book_drf import views, apiview_view, viewset_view, genericviewset_view, modelviewset_view
urlpatterns = [
# url(r'^book_drf/$', apiview_view.as_view()),
# url(r'^book_drf/(?P\d+)/$', apiview_view.as_view()),
# url(r'^books_drf/(?P\d+)/$', apiview_view.BookDRFView.as_view()),
# ViewSet的路由使用方式
# url(r'^book_drf/$', viewset_view.Books.as_view({'get': 'list', 'post': 'create'})),
# url(r'^book_drf/(?P\d+)/$', viewset_view.BookDRFView.as_view({'put': 'update'})),
# url(r'^book_drf/(?P\d+)/lastdata/$', viewset_view.BookDRFView.as_view({'get': 'lastdata'})),
# GenericViewSet的路由使用方式
# url(r'^book_drf/$', genericviewset_view.Books.as_view({'get': 'list', 'post': 'create'})),
# url(r'^book_drf/(?P\d+)/$', genericviewset_view.BookDRFView.as_view({'put': 'update'})),
# url(r'^book_drf/(?P\d+)/lastdata/$', genericviewset_view.BookDRFView.as_view({'get': 'lastdata'})),
# ModelViewSet的路由使用方式
url(r'^book_drf/$', modelviewset_view.Books.as_view({'get': 'list', 'post': 'create'})),
url(r'^book_drf/(?P\d+)/$', modelviewset_view.Books.as_view({'put': 'update',
'get': 'retrieve',
'delete': 'destroy'})),
]
路由匹配的实际方法,从books看是没有,但是点进去看ModelViewSet看是从这继承的
进入ListModelMixin里可以看到,这个类里面有个list方法,其他增删改查同理。
二、对拓展类里的名称,自定义路由,
自定义的路由使用的前提,这个类视图是视图集,如果不是视图集是不能用的。
1、首先引入这个类
from rest_framework.routers import SimpleRouter, DefaultRouter
还有一个DefaultRouter ,有根目录首页匹配功能,如果访问的是http://127.0.0.1可以匹配,如果是SimpleRouter 访问http://127.0.0.1/ 必须加上/,可以从源码上看出,DefaultRouter继承了SimpleRouter。点SimpleRouter的源码可以看下,它已经封装好了方法,做一一映射。
然后初始化生成路由对象
router = SimpleRouter()
router对象下面有个registry方法,用于生成路由对象
第一个参数是资源名字,第二个参数是哪个视图文件下的那个类视图,第三个参数是路由命名
router.registry('book_drf', modelviewset_view.Books, base_name='books')
生成后的路由信息,可以通过一个打印方法看下
print(router.urls)
最后是把这个列表加到一起
urlpatterns +=router.urls
from rest_framework.routers import SimpleRouter, DefaultRouter
# 自定义路由
router = SimpleRouter()
router.registry('book_drf', viewset=modelviewset_view.Books, base_name='books')
print(router.urls)
urlpatterns +=router.urls
三、如果想要对自定义命名的方法,自动生成路由,这个时候使用@action装饰器
from rest_framework.viewsets import ModelViewSet
from testdjango.models import BookInfo
from book_drf.serializer import BookSerializer
from rest_framework.response import Response
from rest_framework.decorators import action
class Books(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookSerializer
# 定义如果超出那五个方法之外的方法,需要使用action装饰器
@action(methods=['get'], detail=True)
def lastdata(self, request, pk):
book = BookInfo.objects.get(id=pk)
ser = BookSerializer(book)
return Response(ser.data)
四、self.action
self.action,可以看出请求的是谁,根据不同的请求返回不同的序列化器。这种场景使用概率比较小
from rest_framework.viewsets import ModelViewSet
from testdjango.models import BookInfo
from book_drf.serializer import BookSerializer
from rest_framework.response import Response
class Books(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookSerializer
# 根据这方法可以看出请求的是谁,返回哪个序列化器
def get_serializer_class(self):
if self.action == 'lastdata':
return BookSerializer
else:
return BookSerializer
# 定义如果超出那五个方法之外的方法,需要使用action装饰器
@action(methods=['get'], detail=True)
def lastdata(self, request, pk):
# 使用self.action 获取请求的是哪个方法,可以根据请求的是哪个
print(self.action)
book = BookInfo.objects.get(id=pk)
ser = self.get_serializer_class(book)
return Response(ser.data)