1
0

More than 3 years have passed since last update.

[メモ] DRF ModelViewSet で POST オーバライドして新規投稿(PUT)と更新(PUT)に振り分ける

Last updated at Posted at 2021-08-16
本シリーズのトップページ
https://qiita.com/robozushi10/items/4559a281d0319eb62c6c

はじめに

次のように、DRF の View で POST されたデータに応じて
「POST」(新規投稿) と「PUT」(更新) に処理を振り分ける例.

POST されたデータについて 実行内容 アクション
テーブルに登録済みのレコードである テーブル上の既存レコードを更新する PUT に相当する
テーブルに未登録のレコードである テーブルに新規登録する POST

サンプルコード

『PC(パソコン) を管理』するデータベース」を例にする.

pclist/models.py

モデルは次の通り.
「OS情報」「ホスト名(主キー)」「IPアドレス」情報を持つ.
ここでは、変数名と型をさらっと見る程度で OK.

class Pclist(models.Model):
  os = models.CharField(verbose_name='OS情報', max_length=64, blank=True, null=True)
  hostname = models.CharField(primary_key=True, verbose_name='ホスト名', max_length=32)
  ipaddr = models.CharField(verbose_name='IPアドレス', max_length=64, blank=True, null=True)
  

apiv1/views.py

DRF の view である.

・(下記🛑より) request.data['フィールド名'] でペイロードの各要素にアクセスできる
・(下記💚より) POST されたデータに一致するレコードが DB に存在しているか
・(下記🔵より) 動的にクラスメンバにアクセスする (Python の文法)

class PclistViewSet(viewsets.ModelViewSet):
  queryset = Pclist.objects.all()
  serializer_class = PclistSerializer # 後述の「apiv1/serializers.py」を参照

  def create(self, request, *args, **kwargs):
    """Pclist オブジェクトの登録に対応するアクションメソッド"""
    # すでに DB に POST された PC が存在するか否かのフラグ
    exists = False
    # POST されたペイロードに「hostname」の値が存在するか? 
    if request.data['hostname']: 🛑
      # DB に「hostname」に該当するマシン名が存在しているか?
💚    exists = Pclist.objects.filter(hostname__exact=request.data['hostname']).exists()

    # すでに DB に該当するマシン名が存在する場合
    if exists == True:
      # DB から該当するレコードを取り出す
      pclist = Pclist.objects.get(hostname=request.data['hostname'])
      for k, v in request.data.items():
        # 主キーである「hostname」以外のフィールドを書き換える ... PUT 相当
        if v != "" and k != 'hostname':
          # 「hostname」以外のキーと値があれば上書きする
          setattr(pclist, k, v) 🔵
      # 更新された情報を DB に書き込む
      pclist.save()
      return Response(status=status.HTTP_202_ACCEPTED)
    else:
      # 存在しないホスト名だったので新規投稿する ... POST 相当の処理
      response = super().create(request, *args, **kwargs)
      return response

apiv1/serializers.py

特筆すべき処理はない.

class PclistSerializer(serializers.ModelSerializer):
  class Meta:
    var = ''
    model = Pclist
    fields = ('os', 'hostname', 'ipaddr',)
1
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
1
0