decorators.py views.py

クラスベースビュー

Djangoのクラスベースビューは、旧式のビューからの歓迎すべき脱却です。

Reinout van Rees

REST frameworkは、Djangoの`View`クラスをサブクラス化した`APIView`クラスを提供します。

`APIView`クラスは、通常の`View`クラスとは以下の点で異なります。

  • ハンドラーメソッドに渡されるリクエストは、Djangoの`HttpRequest`インスタンスではなく、REST frameworkの`Request`インスタンスになります。
  • ハンドラーメソッドは、Djangoの`HttpResponse`ではなく、REST frameworkの`Response`を返すことができます。ビューは、コンテンツネゴシエーションを管理し、レスポンスに正しいレンダラーを設定します。
  • `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 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ポリシー実装メソッド

以下のメソッドは、ハンドラーメソッドにディスパッチする前に呼び出されます。

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

ハンドラーメソッドに渡されるリクエストオブジェクトが、通常のDjango `HttpRequest`ではなく、`Request`のインスタンスであることを確認します。

通常、このメソッドをオーバーライドする必要はありません。

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

ハンドラーメソッドから返された`Response`オブジェクトが、コンテンツネゴシエーションによって決定された正しいコンテンツタイプにレンダリングされることを保証します。

通常、このメソッドをオーバーライドする必要はありません。


関数ベースビュー

[クラスベースビュー]が常に優れたソリューションであると言うのは間違いです。

Nick Coghlan

REST frameworkでは、通常の関数ベースビューを使用することもできます。関数ベースビューをラップして、`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 Method Not Allowed」で応答します。この動作を変更するには、ビューが許可するメソッドを次のように指定します。

@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 frameworkはビューに追加できる追加のデコレータを提供します。これらは、`@api_view`デコレータの*後*(下)に配置する必要があります。たとえば、特定のユーザーが1日に1回だけ呼び出すことができるようにスロットルを使用するビューを作成するには、`@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!"})