Quantcast
Channel: Postmanタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 470

Django Rest FrameWork で配列やファイルを含むupdate処理について

$
0
0
はじめに DRFで配列やファイル含むデータを送信する際に、multipart/form-dataで送信したが、PostManでもうまくいかず、FrontEnd側やPostManの使い方と思いこんでしまいはまってしまいました。私がやったやり方は以下のとおりです。 multipart/form-dataで送信 ※前提条件のとおりですが、Base64とか他にもやり方はあるそうです ファイルはFileFieldを使わない ViewSetで、createとupdateをオーバライドする ※Serializerでオーバライドする方法もあるそうですが、よく分かりませんでした。 目次 正解 補足 参考文献 正解 models.py from django.db import models from eqs.models import Eqs, EqTypes class Infos(models.Model): titles = models.CharField(max_length=32) sammary = models.TextField(max_length=100) text = models.TextField() def __str__(self): return self.titles class Files(models.Model): """ ファイル格納用 """ Infos = models.ForeignKey('Infos', on_delete=models.CASCADE, related_name="files") filePath = models.CharField(primary_key=True, max_length=512) def __str__(self): return self.filePath serializer.py from rest_framework import serializers from .models import Infos, Files class InfosSerializer(serializers.ModelSerializer): files = serializers.StringRelatedField(many=True, read_only=True) class Meta: model = Infos fields = "__all__" serializer.py import os from rest_framework import viewsets from rest_framework import status from rest_framework.generics import get_object_or_404 from rest_framework.response import Response from .models import Infos, Files from .serializer import InfosSerializer UPLOAD_DIR = 'media/' # mediaフォルダに格納するためのアップロードパス class InfosViewSet(viewsets.ModelViewSet): queryset = Infos.objects.all() serializer_class = InfosSerializer def create(self, request, *args, **kwargs): info = Infos.objects.create() return self.serialize(request, info) def update(self, request, pk, *args, **kwargs): info = get_object_or_404(Infos, pk=pk) return self.serialize(request, info) def serialize(self, request, bugInfo): serializers = InfosSerializer(instance=Info, data=request.data, partial=True) serializers.is_valid(raise_exception=True) serializers.save() self.delFiles(request) self.setFiles(info, request) return Response(serializers.data, status.HTTP_200_OK) def setFiles(self, info, request): files = request.FILES.getlist('addFiles[]') for file in files: # ファイル保存処理 path = os.path.join(UPLOAD_DIR, file.name) destination = open(path, 'wb') for chunck in file.chunks(): destination.write(chunck) destination.close # model保存処理 if not os.path.exists(path): continue else: fileobj = Files.objects.create(filePath=path, infos=info) fileobj.save() def delFiles(self, request): str_delFiles = request.POST.getlist('delFiles[]') for str_delFile in str_delFiles: fileobj = Files.objects.get(filePath=str_delFile) fileobj.delete() os.remove(str_delFile) 補足 PostManでの確認方法 PostManでの配列の送信方法はkeyの後ろに「[]」を付ければOK(Advanced Rest Clientでも同じ) axiosでの送信方法 save.js // 一部抜粋 save() { const editedId = this.editID; const formData = new FormData(); Object.entries(this.editedItem).forEach(([key, value]) => { if (Array.isArray(value)) { value.forEach((v, i) => { formData.append(key + '[]', v); }); } else { formData.append(key, value); } }); try { if (editedId === -1) { axios.post('/Info/', formData, config).then(postRes => { this.editedItem.id = postRes.data; axios.get('/Info/' + postRes.data.id + '/').then(getRes => { this.infos.push(getRes.data); }); }); this.close(); } else { axios .put('/Info/' + this.editedItem.id + '/', formData, config) .then(putRes => { axios.get('/Info/' + putRes.data.id + '/').then(getRes => { Object.assign(this.infos[editedId], getRes.data); }); }); this.close(); } } catch (error) { alert('DBに保存されませんでした\n' + error); } }, 参考文献 Postmanで配列とファイルをPOSTする話 axiosにFormDataを使ってArrayデータを送信する

Viewing all articles
Browse latest Browse all 470

Trending Articles