Class-based Views

Django's class-based views are a welcome departure from the old-style views. — Reinout van Rees

REST framework提供了一个APIView类,它是Django中View类的子类。

APIView类与常见的View的不同之处在于:

  • 传递给处理方法的请求(Request)是Rest framework的Request的实例,而不是Django的HttpRequest
  • 处理方法可能返回REST framework的Response,而不是Django的HttpResponse。View将会管理内容解析并给respnose设置正确的渲染器;
  • 任何APIException异常都会被捕获并转换为合适的response
  • 请求在被分发到处理器方法之前会被认证和进行权限验证。

APIView类的使用方法和常见的View类基本相同,通常,进来的request会被分发到何时的处理器方法上,比如:.get()`.post()`。另外,可以在控制API策略的不同方面设置许多属性。

例子:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions

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)

API policy attributes

下面的属性控制着API View的各个方面。

.renderer_classes

.parser_classes

.authentication_classes

.throttle_classes

.permission_classes

.content_negotiation_class

API policy instantiation methods

REST framework使用下面的方法来实例化不同的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策略实现方法(API policy implementation methods)

在被分发到不同的处理器方法之前将会调用下面的方法:

.check_permissions(self, request)

.check_throttles(self, request)

.perform_content_negotiation(self, request, force=False)

分发方法(Dispatch methods)

下面的方法将会被view的.dispatch()方法直接调用。它们会在处理器方法如.get().post().put().patch().delete()被调用之前或调用之后执行一些动作。

.initial(self, request, args, *kwargs)

处理器方法被调用之前执行的动作。这个方法常被用来进行权限限制和一些内容解析的任务。 通常不需要覆盖这个方法。

.handle_exception(self, exc)

任何被处理器方法抛出的异常都会传递到此方法,它要么返回一个Response实例,要么抛出一个异常。 该方法的默认实现处理了rest_framework.exceptions.APIException的任何子类类型的异常及Django的Http404PermissionDenied异常,返回一个合适的携带错误信息的response。

.initialize_request(self, request, args, *kwargs)

确保了传送到处理器方法的request对象是Request的实例而不是DjangoHttpRequest的实例。 通常不需要覆盖这个方法。

.finalize_response(self, request, response, args, *kwargs)

确保了从处理器方法返回的Response对象被渲染为内容解析决定的正确的content type。


Function Based Views

Saying [that class-based views] is always the superior solution is a mistake. — Nick Coghlan

REST framework也允许你使用常见的基于函数的视图工作,它提供了一系列简单的装饰器来包装你的视图函数,确保它接收的request对象是Request的实例而不是DjangoHttpRequest的实例,同时允许它返回一个Response(而不是DJango的HttpResponse实例),也允许你配置request的处理器方法。

@api_view()

Signature:@api_view(http_method_names=['GET'], exclude_from_schema=False) 该功能的核心是api_view装饰器,它包含你的视图应该响应的HTTP方法的列表。 例如,这是一个最简单的视图,它仅仅返回一些数据:

from rest_framework.decorators import api_view

@api_view()
def hello_world(request):
    return Response({"message": "Hello, world!"})

这个试图将会使用setsings中指定的默认的渲染器、解析器和认证类。 默认只接受GET方法,其它的方法将会返回“405 Method Not Allowed” response。要想修改默认值,只需指定该视图允许哪些方法即可。如:

@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!"})

你还可以使用exclude_from_schema参数来标记API视图,将它从auto-generated schema中忽略。

@api_view(['GET'], exclude_from_schema=True)
def api_docs(request):
    ...

API policy decorators

为了覆盖默认的设置,REST framework提供了一些可被用到视图中的额外的装饰器。它们必须在@api_view装饰器的后面(下面)。例如,要创建一个视图,使用throllte来保证每个用户每天只能调用一次,使用@throttle_classes装饰器,传递throttle类的列表:

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(...)

这些装饰器中的每一个都需要一个参数,它必须是列表或元组元素。

results matching ""

    No results matching ""