我正在尝试从React前端发布到DRF API。这是反应部分:
handleSubmit(event) {
event.preventDefault();
let album = {'name': this.state.selected_album, 'musician': {'name': this.state.selected_musician}};
let formData = new FormData();
formData.append('title', this.state.title);
formData.append('upload', this.state.file);
formData.append('youtube', this.state.youtube);
formData.append('genre', this.state.selected_genre);
formData.append('album', JSON.stringify(album));
fetch('/api/music/track/', {
body: formData,
method: 'post',
headers: {
'Authorization': 'Token ' + localStorage.getItem('token'),
}
}).then(function (data) {
return data.json();
}).then(function(data) {
console.log(data);
}).catch(function (err) {
console.error(err);
})
}
然后我得到了这个回复:{"album":["This field is required."]}
我检查了浏览器的“网络”标签,没有空的相册字段。 请求正文:
-----------------------------139814953515753314481268355557
Content-Disposition: form-data; name="title"
assa
-----------------------------139814953515753314481268355557
Content-Disposition: form-data; name="youtube"
-----------------------------139814953515753314481268355557
Content-Disposition: form-data; name="genre"
Roc
-----------------------------139814953515753314481268355557
Content-Disposition: form-data; name="album"
{"name":"5ugi5ht5i","musician":{"name":"sdfaf"}}
-----------------------------139814953515753314481268355557--
请求标头:
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Referer: http://localhost:3000/upload
authorization: Token ****
content-type: multipart/form-data; boundary=---------------------------139814953515753314481268355557
origin: http://localhost:3000
Content-Length: 564
Cookie: csrftoken= **; tabstyle=raw-tab
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
序列化器:
class MusicianSerializer(ModelSerializer):
user = serializers.HiddenField(
default=serializers.CurrentUserDefault(),
)
picture = serializers.ImageField(allow_null=True, write_only=True)
picture_thumbnail = serializers.ImageField(read_only=True)
class Meta:
model = Musician
fields = '__all__'
class AlbumSerializer(ModelSerializer):
musician = MusicianSerializer()
user = serializers.HiddenField(
default=serializers.CurrentUserDefault(),
)
picture = serializers.ImageField(allow_null=True, write_only=True)
picture_thumbnail = serializers.ImageField(read_only=True)
class Meta:
model = Album
fields = '__all__'
def create(self, validated_data):
musician_data = validated_data.pop('musician')
musician, created = Musician.objects.get_or_create(user=self.context['request'].user,
name=musician_data['name'])
album = Album.objects.create(musician=musician, **validated_data)
return album
def update(self, instance, validated_data):
pass
class TrackSerializer(ModelSerializer):
user = serializers.HiddenField(
default=serializers.CurrentUserDefault(),
)
album = AlbumSerializer()
musician = MusicianSerializer(read_only=True)
upload = serializers.FileField(allow_null=True)
download = serializers.FileField(allow_null=True, read_only=True)
b2_file_id = serializers.CharField(read_only=True)
class Meta:
model = Track
fields = '__all__'
def create(self, validated_data):
album_data = validated_data.pop('album')
musician_data = album_data['musician']['name']
musician, created = Musician.objects.get_or_create(user=self.context['request'].user,
name=musician_data)
album, created = Album.objects.get_or_create(user=self.context['request'].user,
name=album_data['name'])
track = Track.objects.create(album=album, musician=musician, **validated_data)
return track
但是我可以从DRF api浏览器创建新对象。
答案 0 :(得分:0)
我认为 JSON.stringify()
是元凶。在发送到API之前,它将JSON对象转换为 string 。
所以,改变
formData.append('album', JSON.stringify(album));
到
formData.append('album', album);