0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Django Rest Framework querysetつかうViewset、使わないViewset

Last updated at Posted at 2024-10-05

Django queryset使うやつと使わないViewSetを意識する

querysetを使わない

mixins.CreateModelMixin

class CreateModelMixin:
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}

CreateModelMixinは挙動としてはSerializerを介すだけなので動作は非常に簡単です。
リクエストデータをviewの中で定義したserializerに突っ込んでシリアライズし、入力値の検証を

serializer.is_valid

で行います。

あとはシリアライズしたシリアライザインスタンスをシリアライザのsaveメソッドに渡せば完了です。

もしserializerでの入力値の検証が終わっているかつ保存処理が実行される前に何かしたい場合は、perform_createをview内でオーバーライドしましょう。
裏を返せば、簡単にcreateメソッドをオーバーライドするなということです。
どうせcreateメソッドをオーバーライドしたところで、シリアライズすることと入力値の検証をしないといけないことは変わらないので。
Djangoがプログラマに最低限のところだけオーバーライドしなよ。と伝えてくれてるわけです。

perform_creteの使い方例
特定のModelのデータをsaveした直後にひもづくレコードを作りたい時

def perform_create(self, serializer):
    instance = serializer.save()
    Profile.objects.create(user=instance)

querysetを使う

mixins.CreateModelMixin以外のmixinは、全てquerysetを使います。
そのため、mixinがquerysetを扱うためによく使うメソッドを覚えておきましょう。

viewを作る際にmixinsと一緒にほぼからなず一緒に継承するGenericViewsetにはこのように書かれています

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    """
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    """
    pass

does include the base set of generic view behavior, such as the get_object and get_queryset methods.

とあるように、get_objectとget_querysetのような「汎用的な」セットが含まれている、とあります。

特にget_querysetはよく使いますので覚えておいてください

1. get_queryset

def get_queryset(self):
    """
    Get the list of items for this view.
    This must be an iterable, and may be a queryset.
    Defaults to using `self.queryset`.

    This method should always be used rather than accessing `self.queryset`
    directly, as `self.queryset` gets evaluated only once, and those results
    are cached for all subsequent requests.

    You may want to override this if you need to provide different
    querysets depending on the incoming request.

    (Eg. return a list of items that is specific to the user)
    """
    assert self.queryset is not None, (
        "'%s' should either include a `queryset` attribute, "
        "or override the `get_queryset()` method."
        % self.__class__.__name__
    )

    queryset = self.queryset
    if isinstance(queryset, QuerySet):
        # Ensure queryset is re-evaluated on each request.
        queryset = queryset.all()
    return queryset

view内で定義されたquerysetを返します。querysetは必ず定義しないといけません。
コードにあるようにquerysetがないとエラーが起きます。
view内でquerysetを自分用にカスタマイズしたい時は、このget_querysetをオーバーライドします。

以上になります。読んでいただきありがとうございます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?