Serializer の create() と ModelViewset の perform_create() をいつ使用するか 質問する

Serializer の create() と ModelViewset の perform_create() をいつ使用するか 質問する

モデル オブジェクトの作成に関する Django-rest-framework のドキュメントを明確にしたいと思います。これまでのところ、このようなイベントを処理する方法には 3 つのアプローチがあることがわかりました。

  1. シリアライザのcreate()メソッド。ドキュメンテーション

    class CommentSerializer(serializers.Serializer):
    
        def create(self, validated_data):
            return Comment.objects.create(**validated_data)
    
  2. ModelViewsetcreate()メソッド。ドキュメンテーション

    class AccountViewSet(viewsets.ModelViewSet):
    
        queryset = Account.objects.all()
        serializer_class = AccountSerializer
        permission_classes = [IsAccountAdminOrReadOnly]
    
  3. ModelViewsetperform_create()メソッド。ドキュメンテーション

    class SnippetViewSet(viewsets.ModelViewSet):
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    

これら 3 つのアプローチは、アプリケーション環境に応じて重要になります。しかし、各関数はいつ使用する必要があるのでしょうかcreate() / perform_create()。一方、単一の POST リクエストに対して、のModelViewSetcreate()serializer の の2 つの create メソッドが呼び出されたという報告もいくつか見つかりましたcreate()

ベストアンサー1

  1. create(self, validated_data)保存する前にオブジェクトに追加の詳細を追加し、 と同様に各モデル フィールドに値を「プロッド」するには、を使用します**validated_data。理想的には、この形式の「プロッド」は 1 つの場所でのみ実行したいので、 の メソッドがcreate最適CommentSerializerです。さらに、アカウントを独自のデータベースに保存する直前に、外部 API を呼び出してユーザー アカウントを作成することもできます。このcreate関数は と組み合わせて使用​​する必要がありますModelViewSet。常に「薄いビュー、厚いシリアライザー」と考えてください。

    例:

    def create(self, validated_data):
        email = validated_data.get("email", None)
        validated.pop("email") 
        # Now you have a clean valid email string 
        # You might want to call an external API or modify another table
        # (eg. keep track of number of accounts registered.) or even
        # make changes to the email format.
    
        # Once you are done, create the instance with the validated data
        return models.YourModel.objects.create(email=email, **validated_data)
    
  2. の関数create(self, request, *args, **kwargs)は、 の親である クラスModelViewSetで定義されています。の主な関数は次のとおりです。CreateModelMixinModelViewSetCreateModelMixin

    from rest_framework import status
    from rest_framework.response import Response
    
    
    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()
    

    ご覧のとおり、上記のcreate関数はシリアライザーで検証を呼び出し、正しい応答を生成します。この背後にある利点は、アプリケーション ロジックを分離して、日常的で反復的な検証呼び出しや応答出力の処理について心配する必要がなくなることです :)。これは、create(self, validated_data)シリアライザー (特定のアプリケーション ロジックが存在する可能性がある場所) にある と組み合わせて使用​​すると非常にうまく機能します。

  3. perform_create(self, serializer)では、なぜ1行のコードで別の関数を用意するのかと疑問に思うかもしれません。その主な理由は、save関数を呼び出すときにカスタマイズできるようにするためです。関数を呼び出す前に、追加のデータを提供する必要があるかもしれません。save (のようにserializer.save(owner=self.request.user)がなければperform_create(self, serializer)、 をオーバーライドする必要がありcreate(self, request, *args, **kwargs)、これでは重くて退屈な作業をミックスインに実行させる目的が達成されません。

おすすめ記事