DRF-视图

本文详细介绍了Django REST Framework(DRF)中API视图的类型和使用,包括APIView、基于函数的视图、通用API视图、mixin类、具体视图类和ViewSet。讨论了视图集的操作、内省、路由标记以及如何自定义视图行为。同时,讲解了模型视图集和只读模型视图集的用法,展示了如何通过装饰器和mixin类实现不同功能。
摘要由CSDN通过智能技术生成

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方法处理程序。

扩展:GenericAPIViewCreateModelMixin

ListAPI视图

用于只读端点以表示 模型实例的集合

提供get方法处理程序。

扩展:GenericAPIViewListModelMixin

RetrieveAPIView

用于表示单个模型实例的只读端点。

提供get方法处理程序。

扩展:GenericAPIViewRetrieveModelMixin

DestoryAPIView

用于单个模型实例的仅删除端点。

提供delete方法处理程序。

扩展:GenericAPIViewDestroyModelMixin

UpdateAPIView

用于单个模型实例的仅更新端点。

提供putpatch方法处理程序。

扩展:GenericAPIViewUpdateModelMixin

ListCreateAPIView

用于读写端点以表示 模型实例的集合

提供getpost方法处理程序。

扩展:GenericAPIViewListModelMixinCreateModelMixin

RetrieveUpdateAPI视图

用于读取或更新端点以表示 单个模型实例

提供get,putpatch方法处理程序。

扩展:GenericAPIViewRetrieveModelMixinUpdateModelMixin

RetrieveDestroyAPIView

用于读取或删除端点以表示 单个模型实例

提供getdelete方法处理程序。

扩展:GenericAPIViewRetrieveModelMixinDestroyModelMixin

RetrieveUpdateDestroyAPIView

用于读写删除端点以表示 单个模型实例

提供getputpatch方法delete处理程序。

扩展:GenericAPIViewRetrieveModelMixinUpdateModelMixinDestroyModelMixin

视图集

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参数设置为Trueor 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_pathurl_name参数更改 URL 段和操作的反向 URL 名称。

要查看所有额外操作,请调用该.get_extra_actions()方法。

视图集

该类ViewSet继承自APIView. 您可以使用任何标准属性,例如permission_classes,authentication_classes来控制视图集上的 API 策略。

该类ViewSet不提供任何操作实现。为了使用一个ViewSet类,您将覆盖该类并明确定义操作实现。

通用视图集

该类GenericViewSet继承自GenericAPIView,并提供默认的一组get_objectget_queryset方法和其他通用视图基本行为,但默认情况下不包括任何操作。

为了使用一个GenericViewSet类,您将覆盖该类并混合所需的混合类,或显式定义操作实现。

模型视图集

通过混合各种 mixin 类的行为,ModelViewSet该类继承自并包含各种操作的实现。GenericAPIView

ModelViewSet类提供的动作是.list().retrieve().create().update().partial_update().destroy()

只读模型视图集

该类ReadOnlyModelViewSet还继承自GenericAPIView. 与ModelViewSet它一样,它还包括各种操作的实现,但不像ModelViewSet只提供“只读”操作,.list()并且.retrieve().

例子

与 一样ModelViewSet,您通常需要至少提供querysetserializer_class属性。例如:

classAccountViewSet(viewsets.ReadOnlyModelViewSet):
    """
    A simple ViewSet for viewing accounts.
    """
    queryset =Account.objects.all()
    serializer_class =AccountSerializer

同样,与 一样ModelViewSet,您可以使用任何可用于 的标准属性和方法覆盖GenericAPIView

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值