DRF-视图集ModelViewSet和自定义路由

一、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\d+)/$', modelviewset_view.Books.as_view({'put': 'update', 'get': 'retrieve', 'delete': 'destroy'})),


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看是从这继承的

DRF-视图集ModelViewSet和自定义路由_第1张图片

 进入ListModelMixin里可以看到,这个类里面有个list方法,其他增删改查同理。

DRF-视图集ModelViewSet和自定义路由_第2张图片

二、对拓展类里的名称,自定义路由

自定义的路由使用的前提,这个类视图是视图集,如果不是视图集是不能用的。

1、首先引入这个类

from rest_framework.routers import SimpleRouter, DefaultRouter

还有一个DefaultRouter ,有根目录首页匹配功能,如果访问的是http://127.0.0.1可以匹配,如果是SimpleRouter 访问http://127.0.0.1/ 必须加上/,可以从源码上看出,DefaultRouter继承了SimpleRouter。点SimpleRouter的源码可以看下,它已经封装好了方法,做一一映射。

DRF-视图集ModelViewSet和自定义路由_第3张图片

然后初始化生成路由对象

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)

你可能感兴趣的:(Django,django,restful,python)