基于类的视图
Django 的基于类的视图是旧式视图的一个受欢迎的替代品。
REST 框架提供了一个 APIView
类,它是 Django 的 View
类的子类。
APIView
类与常规 View
类有以下不同之处
- 传递给处理程序方法的请求将是 REST 框架的
Request
实例,而不是 Django 的HttpRequest
实例。 - 处理程序方法可以返回 REST 框架的
Response
,而不是 Django 的HttpResponse
。视图将管理内容协商并在响应中设置正确的渲染器。 - 任何
APIException
异常都将被捕获并调解成适当的响应。 - 传入的请求将经过身份验证,并在将请求分发到处理程序方法之前运行适当的权限和/或节流检查。
使用 APIView
类与使用常规 View
类几乎相同,与往常一样,传入的请求被分发到适当的处理程序方法,例如 .get()
或 .post()
。此外,可以在类上设置许多属性来控制 API 策略的各个方面。
例如
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
from django.contrib.auth.models import User
class ListUsers(APIView):
"""
View to list all users in the system.
* Requires token authentication.
* Only admin users are able to access this view.
"""
authentication_classes = [authentication.TokenAuthentication]
permission_classes = [permissions.IsAdminUser]
def get(self, request, format=None):
"""
Return a list of all users.
"""
usernames = [user.username for user in User.objects.all()]
return Response(usernames)
注意:Django REST Framework 的 APIView
、GenericAPIView
、各种 Mixins
和 Viewsets
的完整方法、属性和关系最初可能很复杂。除了此处的文档之外,Classy Django REST Framework 资源还提供了可浏览的参考,其中包含 Django REST Framework 的每个基于类的视图的完整方法和属性。
API 策略属性
以下属性控制 API 视图的可插入方面。
.renderer_classes
.parser_classes
.authentication_classes
.throttle_classes
.permission_classes
.content_negotiation_class
API 策略实例化方法
REST 框架使用以下方法实例化各种可插拔 API 策略。你通常不需要覆盖这些方法。
.get_renderers(self)
.get_parsers(self)
.get_authenticators(self)
.get_throttles(self)
.get_permissions(self)
.get_content_negotiator(self)
.get_exception_handler(self)
API 策略实现方法
在分派到处理程序方法之前调用以下方法。
.check_permissions(self, request)
.check_throttles(self, request)
.perform_content_negotiation(self, request, force=False)
分发方法
视图的 .dispatch()
方法直接调用以下方法。这些方法执行在调用处理程序方法(如 .get()
、.post()
、put()
、patch()
和 .delete()
)之前或之后需要执行的任何操作。
.initial(self, request, *args, **kwargs)
执行在调用处理程序方法之前需要执行的任何操作。此方法用于强制执行权限和限制,并执行内容协商。
你通常不需要覆盖此方法。
.handle_exception(self, exc)
处理程序方法引发的任何异常都将传递给此方法,该方法返回 Response
实例或重新引发异常。
默认实现处理 rest_framework.exceptions.APIException
的任何子类,以及 Django 的 Http404
和 PermissionDenied
异常,并返回适当的错误响应。
如果你需要自定义 API 返回的错误响应,则应对此方法进行子类化。
.initialize_request(self, request, *args, **kwargs)
确保传递给处理程序方法的请求对象是 Request
的实例,而不是通常的 Django HttpRequest
。
你通常不需要覆盖此方法。
.finalize_response(self, request, response, *args, **kwargs)
确保从处理程序方法返回的任何 Response
对象将被呈现为正确的内容类型,由内容协商决定。
你通常不需要覆盖此方法。
基于函数的视图
说 [基于类的视图] 始终是更好的解决方案是一个错误。
REST 框架还允许你使用基于常规函数的视图。它提供了一组简单的装饰器,用于包装基于函数的视图,以确保它们接收 Request
实例(而不是常规的 Django HttpRequest
),并允许它们返回 Response
(而不是 Django HttpResponse
),并且允许你配置请求的处理方式。
@api_view()
签名: @api_view(http_method_names=['GET'])
此功能的核心是 api_view
装饰器,它采用一个你的视图应响应的 HTTP 方法列表。例如,以下是如何编写一个非常简单的视图,它只手动返回一些数据
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view()
def hello_world(request):
return Response({"message": "Hello, world!"})
此视图将使用 设置中指定的默认渲染器、解析器、认证类等。
默认情况下,只接受 GET
方法。其他方法将响应“405 方法不被允许”。要更改此行为,请指定视图允许的方法,如下所示
@api_view(['GET', 'POST'])
def hello_world(request):
if request.method == 'POST':
return Response({"message": "Got some data!", "data": request.data})
return Response({"message": "Hello, world!"})
API 策略装饰器
要覆盖默认设置,REST 框架提供了一组其他装饰器,可以添加到你的视图中。这些装饰器必须位于 @api_view
装饰器之后(下方)。例如,要创建一个使用 节流 的视图,以确保特定用户每天只能调用一次,请使用 @throttle_classes
装饰器,传递一个节流类列表
from rest_framework.decorators import api_view, throttle_classes
from rest_framework.throttling import UserRateThrottle
class OncePerDayUserThrottle(UserRateThrottle):
rate = '1/day'
@api_view(['GET'])
@throttle_classes([OncePerDayUserThrottle])
def view(request):
return Response({"message": "Hello for today! See you tomorrow!"})
这些装饰器对应于上面描述的 APIView
子类上设置的属性。
可用的装饰器有
@renderer_classes(...)
@parser_classes(...)
@authentication_classes(...)
@throttle_classes(...)
@permission_classes(...)
这些装饰器中的每一个都采用一个参数,该参数必须是类列表或元组。
视图模式装饰器
要覆盖基于函数的视图的默认架构生成,你可以使用 @schema
装饰器。它必须位于 @api_view
装饰器之后(下方)。例如
from rest_framework.decorators import api_view, schema
from rest_framework.schemas import AutoSchema
class CustomAutoSchema(AutoSchema):
def get_link(self, path, method, base_url):
# override view introspection here...
@api_view(['GET'])
@schema(CustomAutoSchema())
def view(request):
return Response({"message": "Hello for today! See you tomorrow!"})
此装饰器采用一个 AutoSchema
实例、一个 AutoSchema
子类实例或 ManualSchema
实例,如 架构文档 中所述。你可以传递 None
以将视图排除在架构生成之外。
@api_view(['GET'])
@schema(None)
def view(request):
return Response({"message": "Will not appear in schema!"})