首页 > 其他分享 >django-rest-framework-从零开始-9-视图类ModelViewSet的使用

django-rest-framework-从零开始-9-视图类ModelViewSet的使用

时间:2023-03-21 19:12:43浏览次数:43  
标签:list ModelViewSet 视图 django student path 路由 view

django-rest-framework-从零开始-9-视图类ModelViewSet的使用

1、前言

在之前(django-rest-framework-从零开始-7-通用的视图类的使用),我们通过简单几步,就可以创建出简单CRUD的drf项目,通过路由的list和detail路径, 分别指向不同的视图类,即List类和Detail类。

路由如下

image-20230320101213260

视图类如下

image-20230320101259239

但是,他们之间,也有相同的代码,都需要指定模型类和序列化视图。那么是否有一个公用类,可以直接代替这两个类,完成最终的基类,实现只要告知一次模型类和序列化类即可。

2、创建ModelViewSet类视图(模型视图类)

(1)改造student_manager/views.py文件

class StudentViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

图示

image-20230320101647294

说明:

  • 我们把StudentListStudentDetail重命名为StudentViewSet,然后继承ModelViewSet,直接完成了类的合二为一

  • 可以看到ModelViewSet类,继承了CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin, GenericViewSet类,这几个类,就是之前的RetrieveUpdateDestroyAPIView类和ListCreateAPIView类的基类,相当于ModelViewSet类,把它们合二为一了,完成了真正的基类,通过ModelViewSet类,我们只需要告知一次模型类和序列化类即可。

(2)路由改造

在此之前,我们需要通过路由,list指向StudentList视图,detail指向StudentDetail视图,那么我们把StudentListStudentDetail合二为一了,是否也能直接把路由合二为一?

我们细想一下,它们直接的其他请求方式,获取所有数据和创建数据不需要主键PK,而检索一条数据和修改、删除、更新一条数据需要主键PK,因此,还是分不开,所以,我们这么改造路由。

改造student_manager/urls.py路由文件

from django.urls import path, re_path

# from student_manager.views import student_list, student_detail
# from student_manager.views import StudentList, StudentDetail
from student_manager.views import StudentViewSet

urlpatterns = [
    # path('list/', student_list),
    # re_path(r'detail/([0-9]+)/', student_detail),
    # path('list/', StudentList.as_view()),
    # re_path(r'detail/([0-9]+)/', StudentDetail.as_view()),
    # re_path(r'detail/(?P<pk>[0-9]+)/', StudentDetail.as_view()),

    path('', StudentViewSet.as_view({'get': 'list', 'post': 'create'})),
    re_path(r'(?P<pk>[0-9]+)/', StudentViewSet.as_view({'get': 'retrieve',
                                                        'put': 'update',
                                                        'patch': 'partial_update',
                                                        'delete': 'destroy'})),
]

图示

image-20230320103137539

说明:

  • 我们直接去掉了list和detail关键字,直接通过是否携带主键PK来决定走哪一种视图,带有PK的路由,就走detail路由对应的视图,不带PK的路由,就走list路由对应的视图,这里把两个关键字直接去掉了,然后通过as_view函数来显示定义出请求方式对应的视图函数,请注意,这里的as_view函数不再是之前View基类的as_view函数。而是ViewSetMixin类的as_view函数,可不要混淆了。
  • 我们得告诉路由,什么请求方式用哪一个函数作为视图,因此,我们显示定义了这样的字典{'get': 'list', 'post': 'create'}{'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}这样,当请求来临时,就可以找到对应处理的视图函数

3、启动服务,测试类视图

测试和之前一样。

4、模型视图通用URL改造

在上面,我们的路由,其实都是相同的,增加一个模型类,我们增加序列化类和模型视图类,都需要增加两个路由,且内容都一样,只是模型视图类不一致,后面as_view函数的参数都一致,因此,drf提供了针对于模型视图的路由注册通用方法。

  • 改造student_manager/urls.py路由文件

    from django.urls import path, include
    # from student_manager.views import student_list, student_detail
    # from student_manager.views import StudentList, StudentDetail
    from rest_framework.routers import DefaultRouter
    
    from student_manager.views import StudentViewSet
    
    router = DefaultRouter()
    router.register('', StudentViewSet)
    
    urlpatterns = [
        # path('list/', student_list),
        # re_path(r'detail/([0-9]+)/', student_detail),
        # path('list/', StudentList.as_view()),
        # re_path(r'detail/([0-9]+)/', StudentDetail.as_view()),
        # re_path(r'detail/(?P<pk>[0-9]+)/', StudentDetail.as_view()),
    
        # path('', StudentViewSet.as_view({'get': 'list', 'post': 'create'})),
        # re_path(r'(?P<pk>[0-9]+)/', StudentViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),
    
        path('', include(router.urls)),
    ]
    

图示

image-20230320105012692

说明:

  • 我们只需要简单的把模型类视图注册到路由即可。

  • 通过查看了源码,可以看到,就是把我们之前的显示表达的映射关系,给定义出来,然后映射出去。直接替我们完成了映射请求方式与处理视图的代码。

    image-20230320105447894

4、跋文

最终,我们如果想要编写一个drf的项目,完成简单的CRUD,则只需要以下几步

(1)定义模型,例如class Student(models.Model):

(2)通过继承ModelSerializer类定义序列化类,例如class StudentSerializer(serializers.ModelSerializer):

(3)通过继承ModelViewSet类定义模型视图类,例如class StudentViewSet(ModelViewSet):

(4)注册路由DefaultRouter().register注册路由,例如router.register('', StudentViewSet)path('', include(router.urls)),

这样,就完成了一个简单的CRUD。可以通过get获取所有数据或单条数据,通过post添加一条数据,通过put修改一条数据,通过delete删除一条数据。相当简单,而且请求的流程也在脑海中,清晰可见。

标签:list,ModelViewSet,视图,django,student,path,路由,view
From: https://www.cnblogs.com/rainbow-tan/p/17241094.html

相关文章

  • django-rest-framework-从零开始-8-Serializer多序列化一个字段
    django-rest-framework-从零开始-8-Serializer多序列化一个字段1、前言这里是属于自己的项目需求,而研究的功能。目的:想在Serializer类中,多显示一个字段。例如:模型使......
  • django-rest-framework-从零开始-6-视图类GenericAPIView的使用
    django-rest-framework-从零开始-6-视图类GenericAPIView的使用1、前言之前提到过的基于APIView类的视图,需要重写["get","post","put","patch","delete","head","opti......
  • django-rest-framework-从零开始-3-序列化类ModelSerializer的使用
    django-rest-framework-从零开始-3-序列化类ModelSerializer的使用1、前言我们之前提到创建序列化类,需要继承serializers.Serializer类,然后映射模型类的字段,然后重写crea......
  • django-rest-framework-从零开始-2-序列化类serializers.Serializer的使用
    django-rest-framework-从零开始-2-序列化类serializers.Serializer的使用1、前言我们编写的django程序,需要与前端或者其他程序交互,通常会提供出自己的API接口,此时需要把......
  • Python Django 加法计算器案例
    创建add应用在templates内新建add.html文件:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Co......
  • Python Django 登陆案例
    在根目录下新建一个templates文件将该目录添加到settings.py文件内在templates文件夹内新建一个login.html文件,并写入模板内容<!DOCTYPEhtml><htmllang="z......
  • django中使用分页器功能
    要使用Django实现分页器,必须从Django中导入Paginator模块fromdjango.core.paginatorimportPaginator假如现在有150条记录要显示,每页显示10条>>>fromdjango.co......
  • 三步打开RabbitMq视图
    RabbitMQ视图使用docker下载安装rabbitMQ#5672是mq默认的端口号#15672是mq默认外界访问的视图端口号#3.10-management指定版本dockerrun-d--restart=alwa......
  • mysql视图
    1.常见的数据库对象2.视图2.1为什么使用视图视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户制定不同的查询视图。比如,针对一个公司的......
  • mysql-connector-python驱动和django-mysql-pool连接池
    ##################### 为了设计一个公用的、安全的连接池接口,可以考虑以下几个方面:封装连接池初始化和获取连接的逻辑,使得调用者不需要了解连接池的具体实现细节,只需要调......