
APIView 是 Django REST Framework (DRF) 中提供的基础视图类,继承自 Django 的 View 类,但针对 RESTful API 进行了扩展。它支持以下功能:
Response 对象,支持内容协商(自动根据客户端需求返回 JSON 等格式)。相比 Django 原生的 View,APIView 更适合构建 RESTful API:
request.POST 或 JsonResponse。get(), post() 等方法实现不同 HTTP 方法逻辑,符合 REST 规范。# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class UserListView(APIView):
def get(self, request):
users = User.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)class UserDetailView(APIView):
def get(self, request, user_id):
user = User.objects.get(id=user_id)
serializer = UserSerializer(user)
return Response(serializer.data)
def post(self, request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)# urls.py
from django.urls import path
from .views import UserListView
urlpatterns = [
path('users/', UserListView.as_view(), name='user-list'),
path('users/<int:pk>/', UserDetailView.as_view(), name='user-detail'),
]request.data:获取解析后的请求体数据(支持 JSON、表单等)。request.query_params:获取 URL 查询参数(等价于 Django 的 request.GET)。request.method: 获取 HTTP 请求方法(如 GET、POST、PUT、DELETE 等)。request.GET: 获取 URL 查询参数(等价于 Django 的 request.GET)。request.content_type: 获取请求的内容类型(Content-Type)。request.POST: 获取请求体中的表单数据(当 Content-Type 为 application/x-www-form-urlencoded 或 multipart/form-data 时)。return Response(
data={'message': 'Success'}, # 响应数据
status=201, # 状态码
headers={'X-Custom': 'value'} # 自定义响应头
)注意!:这实际上是 GenericAPIView 的属性,不是基础 APIView 的属性
APIView 还有一些可以重写的重要方法:
这些属性和方法使 APIView 成为一个非常灵活和可配置的基础视图类,可以根据需要进行定制。
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions, throttling, parsers, renderers
from rest_framework.schemas import AutoSchema
class ExampleAPIView(APIView):
# 渲染器 - 控制响应如何被渲染
renderer_classes = [renderers.JSONRenderer, renderers.BrowsableAPIRenderer]
# 解析器 - 控制如何解析请求数据
parser_classes = [parsers.JSONParser, parsers.FormParser, parsers.MultiPartParser]
# 认证 - 确定请求的用户身份
authentication_classes = [authentication.TokenAuthentication, authentication.SessionAuthentication]
# 权限 - 控制用户是否有权限执行操作
permission_classes = [permissions.IsAuthenticated]
# 限流 - 控制请求频率
throttle_classes = [throttling.UserRateThrottle, throttling.AnonRateThrottle]
# API 模式
schema = AutoSchema()
# 限流范围
throttle_scope = 'example_api'
def get(self, request, format=None):
"""
获取示例数据
"""
data = {'message': '这是一个示例响应'}
return Response(data)
def post(self, request, format=None):
"""
创建示例数据
"""
data = request.data
# 处理数据...
return Response({'received': data})
# 重写初始化方法
def initial(self, request, *args, **kwargs):
"""
在处理请求前执行初始化操作
"""
# 调用父类的 initial 方法
super().initial(request, *args, **kwargs)
# 自定义初始化逻辑
print(f"处理来自 {request.user} 的请求")
# 自定义异常处理
def handle_exception(self, exc):
"""
自定义异常处理
"""
if isinstance(exc, CustomException):
# 处理自定义异常
return Response({'error': str(exc)}, status=400)
# 其他异常交给父类处理
return super().handle_exception(exc)from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions
# 自定义权限类
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
# 读取权限允许任何请求
if request.method in permissions.SAFE_METHODS:
return True
# 写入权限只允许对象的所有者
return obj.owner == request.user
class UserProfileView(APIView):
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
def get(self, request, user_id):
# 获取用户资料
return Response({"user_id": user_id, "data": "用户资料"})
def put(self, request, user_id):
# 更新用户资料
return Response({"message": "资料已更新"})
# 重写获取权限方法
def get_permissions(self):
"""
根据请求方法动态设置权限
"""
if self.request.method == 'DELETE':
return [permissions.IsAdminUser()]
return [permission() for permission in self.permission_classes]from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, throttling
# 自定义限流类
class BurstRateThrottle(throttling.UserRateThrottle):
rate = '10/minute' # 每分钟10次请求
class SustainedRateThrottle(throttling.UserRateThrottle):
rate = '100/day' # 每天100次请求
class ApiEndpoint(APIView):
authentication_classes = [authentication.TokenAuthentication]
throttle_classes = [BurstRateThrottle, SustainedRateThrottle]
def get(self, request):
return Response({"message": "API响应"})
# 重写获取限流器方法
def get_throttles(self):
"""
根据用户类型动态设置限流
"""
if request.user.is_staff:
# 管理员用户不受限流限制
return []
return [throttle() for throttle in self.throttle_classes]from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.negotiation import DefaultContentNegotiation
from rest_framework.versioning import URLPathVersioning
class VersionedAPI(APIView):
content_negotiation_class = DefaultContentNegotiation
versioning_class = URLPathVersioning
def get(self, request, version):
if version == 'v1':
return Response({"version": "1.0", "data": "旧版API数据"})
return Response({"version": "2.0", "data": "新版API数据"})from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.metadata import SimpleMetadata
from rest_framework.schemas import AutoSchema
class DocumentedAPI(APIView):
metadata_class = SimpleMetadata
schema = AutoSchema(
operation_id_base='example',
component_name='Example',
tags=['example-api']
)
def get(self, request):
"""
获取示例数据。
此端点返回一个示例数据对象。
"""
return Response({"example": "data"})
def post(self, request):
"""
创建新的示例数据。
提交数据将被处理并存储。
"""
return Response({"status": "created"})DRF 自动捕获 APIException 异常,返回标准错误响应。 可自定义异常处理逻辑:
def custom_exception_handler(exc, context):
response = exception_handler(exc, context)
if response:
response.data = {
'error': {
'code': response.status_code,
'message': response.data.get('detail', 'Error occurred')
}
}
return response在 settings.py 中配置:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'myapp.handlers.custom_exception_handler'
}class CustomResponse(Response):
def __init__(self, data, **kwargs):
data = {'code': 0, 'msg': 'success', 'data': data}
super().__init__(data, **kwargs)
return CustomResponse(serializer.data)class FileUploadView(APIView):
parser_classes = [MultiPartParser] # 允许 multipart/form-data
def post(self, request):
file = request.FILES['file']
# 处理文件...class BaseAPIView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
class UserView(BaseAPIView):
def get(self, request):
# 复用基类的认证和权限原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。