diadia

興味があることをやってみる。自分のメモを残しておきます。

DRF PATCHの実装方法

参考

Retrofit 2 — How to Update Objects on the Server (PUT vs. PATCH)

How to make a PATCH request using DJANGO REST framework - Stack Overflow

Serializers - Django REST framework

まずPATCHとは

パッチはインスタンスの更新を行うHTTPプロトコルのメソッドである。インスタンスの更新はPUTとPATCHの2つの方法が存在する。 PUTはインスタンスすべてを書き換えることで、PATCHはインスタンスの一部を書き換えることのようだ。

やり方イメージ

Django Rest Frameworkにはシリアライザがある。シリアライザに変更したい内容、変更したいインスタンス、変更は一部のみを明示するpartial=Trueをシリアライザの引数として渡すことでPATCHが実現される。

Serializers - Django REST framework

もちろん、APIViewのメソッドとしてpatchを宣言するし、シリアライザの結果にたいしてsave()メソッドを実行することは言うまでもない。

サンプル

from .utils import getTokenFromHeader
from .utils import getUserByToken


class ProfileAPIView(APIView):

    authentication_classes = (TokenAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)
    
    def patch(self, request, *args, **kwargs):
        #profileオブジェクトを更新する

        token = getTokenFromHeader(self)
        user_obj = getUserByToken(token)
        profile_obj = Profile.objects.get(user=user_obj)
        serializer = ProfileSerializer(profile_obj, data=request.data, partial=True)
        serializer.save()
        return Response({"result": "success"})

関連記事

エラーが出てpatchを実行できないパターン

AssertionError: The `.update()` method does not support writable nested fields by default.
Write an explicit `.update()` method

この場合はあるモデルを表すJSONの内部に更に他のモデルがネストされている場合にエラーが生じると考えられる。