モデル オブジェクトの作成に関する Django-rest-framework のドキュメントを明確にしたいと思います。これまでのところ、このようなイベントを処理する方法には 3 つのアプローチがあることがわかりました。
シリアライザの
create()
メソッド。ドキュメンテーションclass CommentSerializer(serializers.Serializer): def create(self, validated_data): return Comment.objects.create(**validated_data)
ModelViewset
create()
メソッド。ドキュメンテーションclass AccountViewSet(viewsets.ModelViewSet): queryset = Account.objects.all() serializer_class = AccountSerializer permission_classes = [IsAccountAdminOrReadOnly]
ModelViewset
perform_create()
メソッド。ドキュメンテーションclass SnippetViewSet(viewsets.ModelViewSet): def perform_create(self, serializer): serializer.save(owner=self.request.user)
これら 3 つのアプローチは、アプリケーション環境に応じて重要になります。しかし、各関数はいつ使用する必要があるのでしょうかcreate() / perform_create()
。一方、単一の POST リクエストに対して、のModelViewSet
とcreate()
serializer の の2 つの create メソッドが呼び出されたという報告もいくつか見つかりましたcreate()
。
ベストアンサー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)
の関数
create(self, request, *args, **kwargs)
は、 の親である クラスModelViewSet
で定義されています。の主な関数は次のとおりです。CreateModelMixin
ModelViewSet
CreateModelMixin
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)
シリアライザー (特定のアプリケーション ロジックが存在する可能性がある場所) にある と組み合わせて使用すると非常にうまく機能します。perform_create(self, serializer)
では、なぜ1行のコードで別の関数を用意するのかと疑問に思うかもしれません。その主な理由は、save
関数を呼び出すときにカスタマイズできるようにするためです。関数を呼び出す前に、追加のデータを提供する必要があるかもしれません。save
(のようにserializer.save(owner=self.request.user)
がなければperform_create(self, serializer)
、 をオーバーライドする必要がありcreate(self, request, *args, **kwargs)
、これでは重くて退屈な作業をミックスインに実行させる目的が達成されません。