Skip to main content

基于类的视图3-使用视图集

我们将探讨Django Rest Framework(DRF)对视图的第三种扩展方式,即使用视图集(viewsets)。为什么称其为视图集呢?这是因为它将一系列操作进行了集合处理,包括列表展示、新增数据、查看详情、修改信息、删除等。我们可以将这些操作看作是一个集合,而视图集的作用就是将它们整合在一起。在之前的代码中,我们创建了两个类,并在序列化器(serializer)中也创建了两个。如下图所示:

01序列化两个.jpg

实际上,对于我们的REST接口来说,我们只是在操作一个接口,即/api/moive,对电影进行各种操作。那么,能不能将它们作为一个集合呢?视图集的作用就是将这些功能整合在一起。现在我们开始新定义一个视图集,命名为MovieViewSet。让它继承DRF提供的ModelViewSet,并导入相应的模块。修改代码如下:

# 从Django中导入render函数
from django.shortcuts import render
# 从Django中导入JsonResponse类
from django.http import JsonResponse,Http404
# 从rest_framework.decorators模块中导入@api_view装饰器
from rest_framework.decorators import api_view
# 从rest_framework模块中导入status常量和Response类
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import generics
from rest_framework import mixins
from rest framework import viewsets

# 从当前目录下导入Movie模型和MovieListSerializer序列化器
from .models import Movie
from .serializers import MovieSerializer

class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializer

我们在queryset 中使用了之前的查询对象,即Movie.objects.all。在serializer_class 中,我们新定义了一个MovieSerializer,用于对电影进行序列化。这个MovieSerializer同样继承了DRF提供的ModelSerializer

接下来我们在movie /serializers.py文件中来修改代码:

# 导入 REST Framework 中的序列化模块和 movie 应用中的电影模型
from rest_framework import serializers
from movie.models import Movie

# 定义电影序列化器类
class MovieSerializer(serializers.ModelSerializer):

class Meta:
# 指定序列化器所使用的模型
model = Movie
# 指定需要序列化的字段为所有字段
fields = '__all__'

接下来我们定义路由。在全局的URL配置中,我们使用了DRF提供的DefaultRouter。这样,我们就可以通过路由注册的方式将我们的接口注册到全局路由中。这样的话,我们在创建新的路由时,只需在全局路由下进行添加,而访问API后面的对应接口时,就会自动使用include进行包含。在我们的dx_movie/dx_movie/urls.py文件中修改代码如下:

# 导入 Django 中的管理模块、路径模块和包含默认路由器的 REST Framework 模块
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from movie import views

# 创建默认路由器对象
router = DefaultRouter()
# 注册 movie 视图集到路由器中,并指定路径前缀为 'movie'
router.register(r'movie', views.MovieViewSet)

# 定义 URL 路由列表
urlpatterns = [
# 设置 admin 管理路径
path('admin/', admin.site.urls),
# 设置 API 路径,包括注册的视图集路由
path('api/', include(router.urls))
]

最后,我们将原始的movie/urls.py文件内容全部注释掉,因为通过视图集的方式,DRF会按照其规则将所有电影的增删改查操作自动进行路由注册。

现在回到我们的postman中,我们可以尝试一下各个接口效果。在请求中,我们可以看到API/Movie,然后查询、新增、获取详情、修改和删除电影的操作都可以在这一个接口下完成。如下图所示:

02各种操作.jpg

这样,我们通过视图集实现了各种操作的集合,使得代码更为简洁。总的来说,视图集的最大优势在于最大程度地减少了所需的代码量,使我们能够专注于API的交互和表现形式,甚至可以忽略URL的细节。然而,由于抽象程度较高,一些需要定制化的需求可能需要特殊处理。在选择使用views、genericviews还是viewsets时,可以根据实际情况进行选择。