DRF-视图
APIView
基于函数的视图
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)
基于函数的视图
@api_view()
签名: @api_view(http_method_names=['GET'])
此功能的核心是api_view
装饰器,它采用您的视图应响应的 HTTP 方法列表。例如,您可以这样编写一个非常简单的视图,只手动返回一些数据
视图将使用设置中指定的默认渲染器、解析器、身份验证类等
API 策略装饰器
为了覆盖默认设置,REST 框架提供了一组额外的装饰器,可以添加到您的视图中。这些必须在装饰器 之后 (下方) 。@api_view
例如,要创建一个使用节流阀的视图,以确保特定用户每天只能调用一次,请使用@throttle_classes
装饰器,并传递一个节流阀类列表:
from rest_framework.decorators import api_view, throttle_classes
from rest_framework.throttling importUserRateThrottle
classOncePerDayUserThrottle(UserRateThrottle):
rate ='1/day'
@api_view(['GET'])
@throttle_classes([OncePerDayUserThrottle])
def view(request):
returnResponse({"message":"Hello for today! See you tomorrow!"})
这些装饰器对应于在APIView
子类上设置的属性,如上所述。
可用的装饰器有:
@renderer_classes(...)
@parser_classes(...)
@authentication_classes(...)
@throttle_classes(...)
@permission_classes(...)
这些装饰器中的每一个都接受一个参数,该参数必须是类的列表或元组。
通用API视图
此类扩展了 REST 框架的APIView
类,为标准列表和详细视图添加了通常需要的行为。
提供的每个具体通用视图都是通过将GenericAPIView
, 与一个或多个 mixin 类组合起来的。
属性
基本设置 :
queryset
- 应该用于从此视图返回对象的查询集。通常,您必须设置此属性或覆盖该get_queryset()
方法。如果您要覆盖视图方法,重要的是您调用get_queryset()
而不是直接访问此属性,因为queryset
将被评估一次,并且这些结果将被缓存以供所有后续请求使用。serializer_class
- 应该用于验证和反序列化输入以及序列化输出的序列化程序类。通常,您必须设置此属性或覆盖该get_serializer_class()
方法。lookup_field
- 用于执行单个模型实例的对象查找的模型字段。默认为'pk'
. 请注意,在使用超链接 API 时,如果您需要使用自定义值,您需要确保API 视图和序列化程序类都设置了查找字段。lookup_url_kwarg
- 用于对象查找的 URL 关键字参数。URL conf 应包含与此值对应的关键字参数。如果未设置,则默认使用与 相同的值lookup_field
。
分页 :
当与列表视图一起使用时,以下属性用于控制分页。
pagination_class
- 对列表结果进行分页时应使用的分页类。默认为与设置相同的值DEFAULT_PAGINATION_CLASS
,即'rest_framework.pagination.PageNumberPagination'
. 设置pagination_class=None
将禁用此视图的分页。
过滤 :
filter_backends
- 应该用于过滤查询集的过滤器后端类列表。默认为与设置相同的值DEFAULT_FILTER_BACKENDS
。
方法
基本方法 :
#get_queryset(self)
可以重写以提供特定于发出请求的用户的动态行为,例如返回查询集。
例如:
def get_queryset(self):
user =self.request.user
return user.accounts.all()
#filter_queryset(self, queryset)
给定一个查询集,使用正在使用的过滤器后端对其进行过滤,返回一个新的查询集。
例如:
def filter_queryset(self, queryset):
filter_backends =[CategoryFilter]
if'geo_route'inself.request.query_params:
filter_backends =[GeoRouteFilter,CategoryFilter]
elif'geo_point'inself.request.query_params:
filter_backends =[GeoPointFilter,CategoryFilter]
for backend in list(filter_backends):
queryset = backend().filter_queryset(self.request, queryset, view=self)
return queryset
#get_serializer_class(self)
返回应该用于序列化程序的类。默认返回serializer_class
属性。
可以重写以提供动态行为,例如使用不同的序列化程序进行读写操作,或者为不同类型的用户提供不同的序列化程序。
例如:
def get_serializer_class(self):
ifself.request.user.is_staff:
returnFullAccountSerializer
returnBasicAccountSerializer
保存和删除钩子 :
以下方法由 mixin 类提供,并提供轻松覆盖对象保存或删除行为。
- #
perform_create(self, serializer)
-CreateModelMixin
保存新对象实例时调用。 - #
perform_update(self, serializer)
-UpdateModelMixin
保存现有对象实例时调用。 - #
perform_destroy(self, instance)
-DestroyModelMixin
删除对象实例时调用。
这些钩子对于设置请求中隐含但不属于请求数据的属性特别有用。例如,您可以根据请求用户或基于 URL 关键字参数设置对象的属性。
def perform_create(self, serializer):
serializer.save(user=self.request.user)
这些覆盖点对于添加在保存对象之前或之后发生的行为也特别有用,例如通过电子邮件发送确认信息或记录更新。
def perform_update(self, serializer):
instance = serializer.save()
send_email_confirmation(user=self.request.user, modified=instance)
您还可以使用这些钩子来提供额外的验证,方法是引发ValidationError()
. 如果您需要在数据库保存时应用一些验证逻辑,这将很有用。例如:
def perform_create(self, serializer):
queryset =SignupRequest.objects.filter(user=self.request.user)
if queryset.exists():
raiseValidationError('You have already signed up')
serializer.save(user=self.request.user)
mixin 类
列表模型混合
提供一种.list(request, *args, **kwargs)
方法,实现列出查询集。
如果查询集被填充,这将返回一个200 OK
响应,其中查询集的序列化表示作为响应的主体。可以选择对响应数据进行分页。
创建模型混合
提供一种.create(request, *args, **kwargs)
方法,实现创建和保存新模型实例。
如果创建了一个对象,则返回一个201 Created
响应,该对象的序列化表示作为响应的主体。如果表示包含名为 的键url
,则Location
响应的标头将填充该值。
如果为创建对象提供的请求数据无效,400 Bad Request
将返回响应,其中错误详细信息作为响应的主体。
检索模型混合
提供一种.retrieve(request, *args, **kwargs)
方法,该方法实现在响应中返回现有模型实例。
如果可以检索到一个对象,则返回一个200 OK
响应,该对象的序列化表示作为响应的主体。否则它将返回一个404 Not Found
.
更新模型混合
提供一种.update(request, *args, **kwargs)
方法,实现更新和保存现有模型实例。
还提供了一个.partial_update(request, *args, **kwargs)
方法,与方法类似update
,只是更新的所有字段都是可选的。这允许支持 HTTPPATCH
请求。
如果一个对象被更新,这将返回一个200 OK
响应,该对象的序列化表示作为响应的主体。
如果为更新对象提供的请求数据无效,400 Bad Request
将返回响应,其中错误详细信息作为响应的主体。
销毁模型混合
提供一种.destroy(request, *args, **kwargs)
实现删除现有模型实例的方法。
如果一个对象被删除,这将返回一个204 No Content
响应,否则它将返回一个404 Not Found
.
具体视图类
以下类是具体的通用视图。如果您使用通用视图,这通常是您将要工作的级别,除非您需要高度自定义的行为。
视图类可以从rest_framework.generics
.
CreateAPIView
用于仅创建端点。
提供post
方法处理程序。
扩展:GenericAPIView、CreateModelMixin
ListAPI视图
用于只读端点以表示 模型实例的集合 。
提供get
方法处理程序。
扩展:GenericAPIView、ListModelMixin
RetrieveAPIView
用于表示单个模型实例的只读端点。
提供get
方法处理程序。
扩展:GenericAPIView、RetrieveModelMixin
DestoryAPIView
用于单个模型实例的仅删除端点。
提供delete
方法处理程序。
扩展:GenericAPIView,DestroyModelMixin
UpdateAPIView
用于单个模型实例的仅更新端点。
提供put
和patch
方法处理程序。
扩展:GenericAPIView、UpdateModelMixin
ListCreateAPIView
用于读写端点以表示 模型实例的集合 。
提供get
和post
方法处理程序。
扩展:GenericAPIView、ListModelMixin、CreateModelMixin
RetrieveUpdateAPI视图
用于读取或更新端点以表示 单个模型实例 。
提供get
,put
和patch
方法处理程序。
扩展:GenericAPIView、RetrieveModelMixin、UpdateModelMixin
RetrieveDestroyAPIView
用于读取或删除端点以表示 单个模型实例 。
提供get
和delete
方法处理程序。
扩展:GenericAPIView、RetrieveModelMixin、DestroyModelMixin
RetrieveUpdateDestroyAPIView
用于读写删除端点以表示 单个模型实例 。
提供get
、put
和patch
方法delete
处理程序。
扩展:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin
视图集
类ViewSet
只是 一种基于类的视图,它不提供任何方法处理程序 ,例如.get()
or .post()
,而是提供操作,例如.list()
and .create()
。
视图集操作
REST framework 中包含的默认路由器将为一组标准的创建/检索/更新/销毁样式操作提供路由,如下所示:
classUserViewSet(viewsets.ViewSet):
"""
Example empty viewset demonstrating the standard
actions that will be handled by a router class.
If you're using format suffixes, make sure to also include
the `format=None` keyword argument for each action.
"""
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
内省 ViewSet 操作
在调度期间,以下属性在ViewSet
.
basename
- 用于创建的 URL 名称的基础。action
- 当前操作的名称(例如list
,,create
)。detail
- 布尔值,指示当前操作是否配置为列表或详细视图。suffix
- 视图集类型的显示后缀 - 反映detail
属性。name
- 视图集的显示名称。这个论点是相互排斥的suffix
。description
- 视图集的单个视图的显示描述。
您可以检查这些属性以根据当前操作调整行为。例如,您可以将权限限制为除list
类似以下操作之外的所有内容:
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
ifself.action =='list':
permission_classes =[IsAuthenticated]
else:
permission_classes =[IsAdminUser]
return[permission()for permission in permission_classes]
标记路由的额外操作
如果您有应该是可路由的临时方法,您可以使用@action
装饰器将它们标记为这样。与常规操作一样,额外操作可能针对单个对象或整个集合。要表明这一点,请将detail
参数设置为True
or False
。路由器将相应地配置其 URL 模式。例如,DefaultRouter
将配置详细操作以包含pk
在其 URL 模式中。
额外操作的更完整示例:
from django.contrib.auth.models importUser
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response importResponse
from myapp.serializers importUserSerializer,PasswordSerializer
classUserViewSet(viewsets.ModelViewSet):
"""
A viewset that provides the standard actions
"""
queryset =User.objects.all()
serializer_class =UserSerializer
@action(detail=True, methods=['post'])
def set_password(self, request, pk=None):
user =self.get_object()
serializer =PasswordSerializer(data=request.data)
if serializer.is_valid():
user.set_password(serializer.validated_data['password'])
user.save()
returnResponse({'status':'password set'})
else:
returnResponse(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
@action(detail=False)
def recent_users(self, request):
recent_users =User.objects.all().order_by('-last_login')
page =self.paginate_queryset(recent_users)
if page isnotNone:
serializer =self.get_serializer(page, many=True)
returnself.get_paginated_response(serializer.data)
serializer =self.get_serializer(recent_users, many=True)
returnResponse(serializer.data)
action
装饰器默认路由请求GET
,但也可以通过设置methods
参数接受其他 HTTP 方法。例如:
@action(detail=True, methods=['post','delete'])
def unset_password(self, request, pk=None):
...
装饰器允许您覆盖任何视图集级别的配置,例如permission_classes
, serializer_class
, filter_backends
…:
@action(detail=True, methods=['post'], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
这两个新操作将在 urls^users/{pk}/set_password/$
和^users/{pk}/unset_password/$
. 使用url_path
和url_name
参数更改 URL 段和操作的反向 URL 名称。
要查看所有额外操作,请调用该.get_extra_actions()
方法。
视图集
该类ViewSet
继承自APIView
. 您可以使用任何标准属性,例如permission_classes
,authentication_classes
来控制视图集上的 API 策略。
该类ViewSet
不提供任何操作实现。为了使用一个ViewSet
类,您将覆盖该类并明确定义操作实现。
通用视图集
该类GenericViewSet
继承自GenericAPIView
,并提供默认的一组get_object
、get_queryset
方法和其他通用视图基本行为,但默认情况下不包括任何操作。
为了使用一个GenericViewSet
类,您将覆盖该类并混合所需的混合类,或显式定义操作实现。
模型视图集
通过混合各种 mixin 类的行为,ModelViewSet
该类继承自并包含各种操作的实现。GenericAPIView
ModelViewSet
类提供的动作是.list()
、.retrieve()
、 .create()
、.update()
、.partial_update()
和.destroy()
。
只读模型视图集
该类ReadOnlyModelViewSet
还继承自GenericAPIView
. 与ModelViewSet
它一样,它还包括各种操作的实现,但不像ModelViewSet
只提供“只读”操作,.list()
并且.retrieve()
.
例子
与 一样ModelViewSet
,您通常需要至少提供queryset
和serializer_class
属性。例如:
classAccountViewSet(viewsets.ReadOnlyModelViewSet):
"""
A simple ViewSet for viewing accounts.
"""
queryset =Account.objects.all()
serializer_class =AccountSerializer
同样,与 一样ModelViewSet
,您可以使用任何可用于 的标准属性和方法覆盖GenericAPIView
。