当前位置:网站首页>DRF学习笔记(五):视图集ViewSet
DRF学习笔记(五):视图集ViewSet
2022-07-27 14:36:00 【fresh_nam】
前言
使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:
- list() 提供一组数据
- retrieve() 提供单个数据
- create() 创建数据
- update() 更新保存数据
- destory() 删除数据
ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。
视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。如:
from rest_framework.response import Response
from demo.models import ClassInfo
from demo.serializers import ClassInfoSerializer
from rest_framework import viewsets, status
class ClassViewSet(viewsets.ViewSet):
# 获取所有班级数据
def list(self, request):
Classes = ClassInfo.objects.all()
serializer = ClassInfoSerializer(Classes, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
try:
Class = ClassInfo.objects.get(id=pk)
except ClassInfo.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = ClassInfoSerializer(Class)
return Response(serializer.data)
在设置路由是,我们可以如下操作
demo/uels.py
from django.urls import path
from demo import views
urlpatterns = [
······
path('classes/', views.ClassViewSet.as_view({
'get': 'list'})),
path('classes/<int:pk>/', views.ClassViewSet.as_view({
'get': 'retrieve'})),
]
结果:

一、常用视图集父类
1) ViewSet
继承自APIView与ViewSetMixin,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{‘get’:‘list’})的映射处理工作。
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
2)GenericViewSet
使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView。
GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView与ViewSetMixin,在实现了调用as_view()时传入字典(如{‘get’:‘list’})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。
举例:
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
class ClassInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = ClassInfo.objects.all()
serializer_class = ClassInfoSerializer
url的定义
demo/urls.py
urlpatterns = [
······
path('classes_set/', views.ClassInfoViewSet.as_view({
'get': 'list'})),
path('classes_set/<int:pk>/', views.ClassInfoViewSet.as_view({
'get': 'retrieve'})),
]
结果和上面的一样:

二、视图集中定义附加action动作
在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。
添加自定义动作需要使用rest_framework.decorators.action装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
action装饰器可以接收两个参数:
- methods: 该action支持的请求方式,列表传递
- detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
(1)True 表示使用通过URL获取的主键对应的数据对象
(2)False 表示不使用URL获取主键
举例:
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
class ClassInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = ClassInfo.objects.all()
serializer_class = ClassInfoSerializer
# detail为False 表示不需要处理具体的BookInfo对象
@action(methods=['get'], detail=False)
def latest(self, request):
"""返回id最后的一个班级"""
Class = ClassInfo.objects.latest('id')
serializer = ClassInfoSerializer(Class)
return Response(serializer.data)
# detail为True,表示要处理具体与pk主键对应的BookInfo对象
@action(methods=['put'], detail=True)
def updata(self, request, pk):
"""修改班级信息"""
Class = self.get_object()
Class.number = request.data.get('number')
Class.grade = request.data.get('grade')
Class.save()
serializer = self.get_serializer(Class)
return Response(serializer.data)
url的定义
demo/urls.py
from django.contrib import admin
from django.urls import path, include
from demo import views
urlpatterns = [
······
path('classes_set/<int:pk>/', views.ClassInfoViewSet.as_view({
'get': 'retrieve', 'put': 'updata'})),
path('classes_set_latest/', views.ClassInfoViewSet.as_view({
'get': 'latest'})),
]
结果:

结束
drf的基本内容就讲完了,不懂的可以在评论区留言。
补充
有时候我们自定义的动作太多,添加路径的时候不方便,所以drf为我们贴心的提供了路由功能,自动为视图集生成路径。
使用:将原来的路由注释,添加如下代码
from django.contrib import admin
from django.urls import path, include, re_path
from demo import views
from rest_framework.routers import DefaultRouter
# urlpatterns = [
# path('classes_set/<int:pk>/', views.ClassInfoViewSet.as_view({'get': 'retrieve', 'put': 'updata'})),
# path('classes_set_latest/', views.ClassInfoViewSet.as_view({'get': 'latest'})),
# ]
# 定义总路径
urlpatterns = []
# 定义路由
classes_router = DefaultRouter()
# 注册路由
classes_router.register("classes_set", views.ClassInfoViewSet, basename="classes_set")
# 将注册路由的路径添加到总路径中
urlpatterns += classes_router.urls
其中,register里面的参数是register(路由前缀,视图集,basename)
访问时的路径则变为: (前缀)/路由前缀/函数名
结果不变(注意路径发生了变化):
边栏推荐
猜你喜欢

后台返回来的是这种数据,是什么格式啊

Jump to the specified position when video continues playing

Spark troubleshooting finishing

C language: string function and memory function

Binder初始化过程

Fluent -- layout principle and constraints

C language: custom type

Implement custom spark optimization rules

Half find

【剑指offer】面试题42:连续子数组的最大和——附0x80000000与INT_MIN
随机推荐
Use double stars instead of math.pow()
Under the ban, the Countermeasures of security giants Haikang and Dahua!
[sword finger offer] interview question 54: the k-largest node of the binary search tree
【剑指offer】面试题49:丑数
synchronized和ReentrantLock的区别
Causes and solutions of deadlock in threads
Three uses of static keyword
[Yunxiang book club issue 13] common methods of viewing media information and processing audio and video files in ffmpeg
设置提示框位置随鼠标移动,并解决提示框显示不全的问题
Breaking through soft and hard barriers, Xilinx releases Vitis unified software platform for developers
折半查找
QT (IV) mixed development using code and UI files
Fluent -- layout principle and constraints
C语言:数据的存储
[Yunxiang book club issue 13] coding format of video files
实体类(VO,DO,DTO)的划分
$router.back(-1)
【剑指offer】面试题39:数组中出现次数超过一半的数字
Spark RPC
First understanding of structure