でJSONを入れ子になりましたか?このことを考えるとジャンゴRESTフレームワークネストされたシリアライザとPOSTは、私はRESTネストされたシリアライザをDjangoのためのファイル(画像)を含むネストされたデータでPOSTリクエストを送信するにはどうすればよいのファイル
は、オブジェクトをJS:
bookData: {
title: 'Anne of Green Gables',
coverImage: File(123456),
pages: 123,
author: {
name: 'Lucy Maud Montgomery',
born: 1874,
profilepicture_set: [
{file: File(234567), description: 'Young L. M. Montgomery'},
{file: File(234568), description: 'Old L. M. Montgomery}
],
quote_set: [
{text: "I'm so glad I live in a world where there are Octobers."},
{text: "True friends are always together in spirit."},
]
},
}
私は私のDjangoのRESTのAPI(私はフロントエンドにVueJSを使用しますが、これは本当に重要ではありません)へのPOSTリクエストを送信したいです。
# views.py
class CreateBookView(generics.CreateAPIView):
serializer_class = CreateBookSerializer
queryset = Book.objects.all()
# serializers.py
class CreateBookSerializer(serializers.ModelSerializer):
author = CreateAuthorSerializer()
class Meta:
model = Book
fields = ('title', 'pages', 'author')
@transaction.atomic
def create(self, validated_data):
author_data = validated_data.pop('author')
uploader = self.context['request'].user
book = Book.objects.create(uploader=uploader, **validated_data)
Author.objects.create(book=book, **author_data)
return book
# models.py
class AuthorManager(models.Manager):
def create(self, **author_data):
quotes_data = author_data.pop('quote_set')
photos_data = author_data.pop('profilepicture_set')
author = Author(**author_data)
author.save()
for quote_data in quotes_data:
Quote.objects.create(author=author, **quote_data)
for photo_data in photos_data :
ProfilePicture.objects.create(author=author, **photo_data)
return author
## Skipping the CreateAuthorSerializer, Quote and ProfilePicture Managers as they are analogous.
## Assume one Author can only write one Book (OneToOneField). No need to look the name up for existing Authors.
私はVueJSにおけるフロントエンドでデータを送信する方法についていくつかの情報を追加したいEDIT
。
sendData(){
var fd = new FormData()
var bookData = {
title: this.$store.getters.title, # 'Anne of Green Gables"
coverImage: this.$store.getters.coverImage, # File(somesize)
pages: this.$store.getters.pages, # 123
author: this.$store.getters.author, # nested object
...
}
fd = objectToFormData(bookData, fd) # external function, see below
this.$http.post('api/endpoint/create/', fd, headers: {
'Content-Type': 'multipart/form-data',
'X-CSRFToken': Cookies.get('csrftoken'),
}
}).then(...)
}
sendData()
は、ボタンクリックで呼び出されます。 objectToFormData
は平坦状にネストされたオブジェクトを変換NPM (click)から外部LIBです。
この溶液(ならびに@Sajiザビエルの溶液)に問題がrequest.data
が元bookData
オブジェクト構造から遠いとRESTシリアライザによって受け入れられない醜いのQueryDictを含んでいることである(すなわち、author
フィールドであります欠落 - これは真実であり、オブジェクトは平坦化されている)。
<QueryDict: {
'title': ['Anne of Green Gables'],
'coverImage':[InMemoryUploadedFile: cover.jpg (image/jpeg)],
'pages': ['123'],
'name': ['Lucy Maud Montgomery'],
'born': ['1874'],
'profilepicture_set[][description]': ['Young L. M. Montgomery', 'Old L. M. Montgomery'],
'profilepicture_set[][file]': [
InMemoryUploadedFile: young.jpg (image/jpeg),
InMemoryUploadedFile: old.jpg (image/jpeg)
],
'quote_set[][text]': [
"I'm so glad I live in a world where there are Octobers.",
"True friends are always together in spirit."
]
}>
どうすればいいですか?それは醜いsoooooのようです。私が考えることは、create()
関数を上書きすることです。
class CreateBookView(generics.CreateAPIView):
(...)
def create(self, request, *args, **kwargs):
book_data = {}
book_data['title'] = request.data['title']
book_data['pages'] = request.data['pages']
book_data['cover_image'] = request.data['coverImage']
book_data['author'] = {}
book_data['author']['name'] = request.data['name']
book_data['author']['born'] = request.data['born']
(...)
serializer = self.get_serializer(data=book_data)
(...)
これはフィールドやnestednessのいくつかのレベルの多数を搭載したモデルのための効果的でない非常に醜いソリューション、(この本/著者は単なるおもちゃの一例である)です。私はそれをどのように処理するかを
?私はポストの方法を変えますか(嬉しいですか?request.data
形式)、この醜いものを扱いますか?
(VueJS/AngularJSで動作します)マルチパートデータを送信するためのJavascriptいるFormData APIを使用することです - 私は、データを送信するために管理しますが、要求の形式がありますDRFシリアライザによる処理には非常に不快です。 – Fidd
マルチパートは私の提案ではなく、(などの保存、検査の実施)のようなシリアライザの機能を使用しrequest.POST.get(データ)を使用して、サーバー内のファイルを保存することはないので、シリアライザのための問題を作成する(または別のファイルを処理してできるようになりますデータのシリアライザハンドル休み) –
私は私が同じを探していた時に、他の解決策を見つけることができませんでした、それはきれいな解決策ではないことを知っていると我々はいるFormDataのアプローチのために行く必要があります。 –