本シリーズのトップページ |
---|
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',)