1. APIView 类介绍
APIView 是 DRF 中所有视图类的基类。它继承自 Django 的 View 类,但增加了许多专为构建 RESTful API 设计的功能。
核心特性
- 基于类的方法处理:与 Django 的
View类似,它将 HTTP 方法(GET, POST, PUT, DELETE 等)映射到类的实例方法上(如.get(),.post())。 - 增强的请求(Request)对象:不再使用 Django 原始的
HttpRequest对象,而是使用 DRF 的Request对象。该对象提供了:- 内容解析:自动解析 JSON、表单数据等传入的数据,并将其转换为 Python 数据类型(通过
request.data访问)。 - 认证检查:提供
request.user和request.auth来访问认证后的用户和令牌信息。
- 内容解析:自动解析 JSON、表单数据等传入的数据,并将其转换为 Python 数据类型(通过
- 增强的响应(Response)对象:使用 DRF 的
Response对象,它可以根据客户端请求的内容类型(如 JSON、HTML)自动渲染内容,无需手动调用JsonResponse。 - 异常处理:内置了异常处理机制,能够自动捕获并返回结构化的、包含适当状态码的 API 错误响应。
- 认证与权限:提供了方便的方式来为视图设置认证(Authentication)和权限(Permission)类。
- 限流(Throttling):支持对 API 的访问频率进行限制。
基本使用示例
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookSerializer
class BookListAPIView(APIView):
"""
列出所有书籍或创建一本新书
"""
def get(self, request, format=None):
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
2. 与其他视图类的对比
DRF 提供了不同抽象级别的视图类,以适应不同的开发场景。APIView 处于中间层,提供了比通用视图更多控制权,但比基于 ViewSet 的视图更底层。
| 特性/视图类 | django.views.View |
rest_framework.views.APIView |
rest_framework.generics.*GenericAPIView |
rest_framework.viewsets.ViewSet / ModelViewSet |
|---|---|---|---|---|
| 所属框架 | Django 核心 | DRF | DRF | DRF |
| 核心功能 | 最基本的 CBV 基类 | 增强了请求/响应,添加了认证、权限等 | 在 APIView 基础上,添加了获取对象、序列化器等快捷方法 |
将一组相关操作(list, create, retrieve...)组织在一个类中 |
| URL 配置 | 手动将 HTTP 方法映射到类方法 | 手动将 HTTP 方法映射到类方法 | 手动将 HTTP 方法映射到类方法(通常与 as_view() 结合) |
使用路由器(Router)自动生成 URL,或将动作手动绑定到视图 |
| 控制度 | 最高,所有逻辑都需自己实现 | 高,控制请求处理流程,但省去了解析、渲染等底层工作 | 中,复用通用逻辑(如获取对象),只需实现核心行为(如 get, post) | 低,遵循约定大于配置的原则,大量逻辑已内置 |
| 代码量 | 最多 | 多 | 较少 | 最少 |
| 适用场景 | 传统的 Django 页面视图或非常特殊、非标准的 API 端点 | 需要精细控制逻辑流程的标准 RESTful API 端点 | 标准的 CRUD 操作,代码结构清晰、统一 | 快速构建完整的 CRUD API,或需要路由器支持的超媒体 API |
详细对比
1. vs. Django View
APIView是View的子类。View是 Django 的核心,用于处理 Web 请求并返回 Web 响应(通常是 HTML)。它处理的是HttpRequest和HttpResponse。APIView是专门为 API 设计的,处理的是 DRF 的Request和Response,提供了构建 REST API 所需的所有工具。
2. vs. GenericAPIView 和具体通用视图(如 ListCreateAPIView)
-
GenericAPIView继承自APIView,增加了用于处理模型实例(queryset) 和序列化器的通用方法。 -
它提供了如
.get_queryset(),.get_object(),.get_serializer()等方法。 -
你通常不会直接使用
GenericAPIView,而是使用它的一系列具体通用视图子类,这些子类将通用行为与 HTTP 方法进行了组合:# 使用 generics.ListCreateAPIView 实现与上面 APIView 相同的功能 from rest_framework import generics class BookListGenericView(generics.ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerializer # .get() 和 .post() 方法已经由父类实现好了 -
对比:使用通用视图可以极大减少重复代码。如果你的视图是标准的 CRUD 操作,强烈推荐使用通用视图。
APIView则在你需要完全自定义逻辑时使用。
3. vs. ViewSet 和 ModelViewSet
-
ViewSet继承自APIView,但它的理念不同。它将一组相关的视图逻辑组织在一个类中,而不是基于 HTTP 方法。 -
例如,一个
BookViewSet可以包含list(),create(),retrieve(),update(),partial_update(),destroy()等动作。 -
ModelViewSet进一步提供了这些动作的默认实现,只需提供queryset和serializer_class,一个完整的 CRUD API 就完成了。from rest_framework import viewsets class BookModelViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer -
最大的优势:与路由器(Router) 配合使用,可以自动生成 URL 配置,极其高效。
from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'books', BookModelViewSet) urlpatterns = router.urls # 自动生成 URLs: /books/ (GET->list, POST->create) # /books/{pk}/ (GET->retrieve, PUT->update, ...) -
对比:
ViewSet的抽象级别最高,用最少的代码提供了最完整的功能,特别适合标准的模型操作。APIView和GenericAPIView提供了更细粒度的控制,适合非标准或需要复杂定制的端点。
总结与选择建议
| 如果你的需求是... | 那么应该选择... |
|---|---|
| 构建传统的、返回 HTML 的页面 | Django View / TemplateView |
| 构建非标准的、需要高度自定义逻辑的 API 端点 | APIView |
| 构建标准的 CRUD API,希望平衡控制力和代码简洁性 | GenericAPIView 及其子类(如 ListAPIView, RetrieveUpdateDestroyAPIView) |
| 快速构建一套完整的、符合 REST 规范的模型 CRUD API,并且希望 URL 配置也能自动化 | ModelViewSet + DefaultRouter |
将多个相关操作(如 /users/{pk}/change_password/)合并到一个视图类中 |
ViewSet + @action 装饰器 |
简单来说,APIView 是 DRF 强大功能的入口和基础。它为你提供了构建 API 所需的核心工具,同时保留了最大的灵活性。当你发现自己在多个 APIView 中重复类似的模式时,就是考虑升级到更高级的 GenericAPIView 或 ViewSet 的时候了。
评论区 0