Meaningless Notebook

我輩は雑記帖である。名はまだない。


全然参考記事が無かった…(´・ω・`)

他の人は Patch メソッドで変更した項目だけを更新してるから排他制御が要らないのかも ?

でも私が実装したのは SPA の画面項目全部を送り付けてるから、排他制御が必要だった。

しょうがないから自分で考えて実装する事にしたのだ… !

まず、

  1. Django rest framework + Django Concurrency はバ-ジョン番号項目が送られないとデフォルトでは排他制御はされない
  2. バ-ジョン番号項目を送ると排他制御が行われる
  3. 排他制御でエラ-となった時、デフォルトだと 500 Internal Server Error が返ってくる

なので、Put 、Patch メソッドは Django Concurrency のバ-ジョン番号項目を必須にすればいい。

まぁそれを実装するのが大変だったんですけど、知識が無さ過ぎて…

1.必須チェックをする Serializer を作る

class HogeUpdateSerializer(HogeSerializer):
    class Meta(HogeSerializer.Meta):
        pass

    def validate(self, attrs):
        if "version" not in attrs:
            raise serializers.ValidationError("更新にはバ-ジョン番号が必須です。")
        else:
            return super().validate(attrs)

2. action で Serializer を切り替える ViewSet を作る

class HogeViewSet(viewsets.ModelViewSet):
    queryset = Hoge.objects.all()
    serializer_class = HogeSerializer
    update_serializer_class = HogeUpdateSerializer
    actions = ["update", "partial_update"]

    def get_serializer_class(self):
        if self.action in self.__class__.actions:
            return self.__class__.update_serializer_class
        else:
            return super().get_serializer_class()

3. CONCURRENCY_HANDLER409 に指定する View を作る

@api_view(["PUT", "PATCH"])
def conflict(*args, **kwargs):
    return Response(status=status.HTTP_409_CONFLICT)

これで更新の時だけ、バ-ジョン番号を必須にさせて Django Concurrency の排他制御を使えるようにした。

テストしてみないと問題が出るかもしれないけど、多分イケる筈… ?

参考元