DRF基本视图——视图集和路由

1、- 继承ModelViewSet(即:拥有基本视图类所有方法
从它的源码可以看到,它不仅继承了(1)五大拓展类,同时也继承了(2)GenericViewSet
在这里插入图片描述
GenericViewSet又继承了ViewSetMixin(提供了自定义视图函数)通用视图类GenericAPIView(提供序列化和反序列化操作方法(查询集类属性、实例化序列化器类))
在这里插入图片描述

  • 视图views.py代码:

from rest_framework.viewsets import ModelViewSet
from .serializers import *
from books_test.models import *


# 继承ModelViewSet
class BooksView(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer
  • 路由映射原由:
    • 原生的Django框架的路由映射规则是请求方式为——GET–>视图get方法,POST–> post方法(即:请求方式是什么,路由器就会自动去找请求方式小写的视图方法)
    • 问:当我们继承ModelViewSet时,DRF内部提供的视图方法为listcreateupdate等等。那么它是如何知道当请求方式为GET时,去找对应的list方法呢?
    • 答:重写路由映射规则(重写as_view()方法,里面传入字典进行映射)
  • 路由映射:如下图代码
from django.contrib import admin
from django.urls import path,re_path

from books_test.views import *

urlpatterns = [
    path('admin/', admin.site.urls),
    # 获取多个对象
    re_path(r'^books/$', BooksView.as_view({'get':'list', 'post': 'create'})),
    # 获取单一资源:GET + /books/(?P<pk>\d+)/ = self.get
    re_path(r'^books/(?P<pk>\d+)/$',BooksView.as_view({
                                        'get': 'retrieve',
                                        'put': 'update',
                                        'patch': 'partial_update',
                                        'delete': 'destroy'
                                    })),
]
  • 2、前面我们已经知道:ModelViewSet继承了GenericViewSet,而GenericViewSet又继承了ViewSetMixin(提供了自定义视图函数)。所以我们可以自定义视图方法latest,如下代码:
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from .serializers import *
from books_test.models import *


class BooksView(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer
    
	# 请求路径:/books/latest/
    def latest(self, request, *args, **kwargs):
        book = self.queryset.latest('bpub_date')  # 最新发布的书
        serializer = self.get_serializer(instance=book)
        return Response(data=serializer.data)
  • 路由映射:re_path(r'^books/latest/$', BooksView.as_view({'get': 'latest'})),指定get方法–>latest视图方法
from django.contrib import admin
from django.urls import path, re_path

from books_test.views import *

urlpatterns = [
    path('admin/', admin.site.urls),
    # 获取多个对象
    re_path(r'^books/$', BooksView.as_view({'get': 'list', 'post': 'create'})),
    re_path(r'^books/latest/$', BooksView.as_view({'get': 'latest'})),
    # 获取单一资源:GET + /books/(?P<pk>\d+)/ = self.get
    re_path(r'^books/(?P<pk>\d+)/$',BooksView.as_view({
                                        'get': 'retrieve',
                                        'put': 'update',
                                        'patch': 'partial_update',
                                        'delete': 'destroy'
                                    })),
]

  • postman测试:
    在这里插入图片描述

  • 3、如果每创建一个视图函数,我们都需要去重写as_view()路由映射,太麻烦,因此我们选择自动映射路由

  • 路由映射三步走

from django.contrib import admin
from django.urls import path, re_path
from rest_framework.routers import SimpleRouter

from books_test.views import *

urlpatterns = [
    path('admin/', admin.site.urls),
]

# 1、实例化路由对象
router = SimpleRouter()
# 2、注册视图集(指定映射规则,如:路由前缀)
router.register(prefix='books', viewset=BooksView)
# 3、把生成的路由映射router.urls -->[re_path(), re_path()....],加入路由列表urlpatterns中
# urlpatterns.extend(router.urls)
urlpatterns += router.urls
  • 4、SimpleRouterDefaultRouter的区别

  • 这里有个问题:

  • 4.1SimpleRouter自动生成的路由不包括自定义的视图函数latest
    只会生成:(指定的prefix:books前缀拼接xxx路径,单独访问127.0.0.1:8000会返回404报错)
    (1)^books/$ [name='bookinfo-list']–>相当于re_path(r'^book/$')
    (2)^books/(?P<pk>[^/.]+)/$ [name='bookinfo-detail']–>相当于re_path(r'^book/<pk>/$')
    在这里插入图片描述

  • 4.2DefaultRouter自动生成的路由也不包括自定义的视图函数latest
    生成的路由和SimpleRouter的区别为:
    在这里插入图片描述

  • 127.0.0.1:8000/books.json可以得到原生的json数据
    在这里插入图片描述

  • 根路由,访问127.0.0.1:8000不会返回404报错,而是返回下面的页面
    在这里插入图片描述

  • 5、action方法装饰器

  • 作用:修饰自定义视图函数,使之能够进行自动路由映射

  • 因为上面两种自动映射路由方法都不会映射自定义视图方法所以我们选择装饰器。
    @action(methods=['get'], detail=False, url_path='latest')

from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from .serializers import *
from books_test.models import *
# action作用:修饰自定义视图函数,使之能够进行自动路由映射
from rest_framework.decorators import action


class BooksView(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer

    # methods: 映射的请求方式
    # url_path: 路径拼接尾缀,默认值是函数名字
    # detail:
    #      True ---> 路径拼接是: 前缀(prefix) + pk正则分组 + 尾缀(url_path)
    #      False ---> 路径拼接是: 前缀(prefix) + 尾缀(url_path)
    @action(methods=['get'], detail=False, url_path='latest')
    def latest(self, request, *args, **kwargs):
        book = self.queryset.latest('bpub_date')  # 最新发布的书
        serializer = self.get_serializer(instance=book)
        return Response(data=serializer.data)
  • 测试:
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值