关系字段上的Django rest框架“此字段必填”

时间:2018-09-26 06:08:32

标签: django reactjs django-rest-framework

我正在尝试从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浏览器创建新对象。

1 个答案:

答案 0 :(得分:0)

我认为 JSON.stringify() 是元凶。在发送到API之前,它将JSON对象转换为 string

所以,改变

formData.append('album', JSON.stringify(album));

formData.append('album', album);