我目前正在使用React的前端和Django的后端设置文件上传。更具体地说,我想通过API将文件+一些数据传递到数据库。
但是在上传文件时出现错误:“提交的数据不是文件。请检查表单上的编码类型。”
models.py(Django)
class Story (models.Model):
title = models.CharField(max_length=100,blank=False)
content = models.TextField(blank=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
audio = models.FileField(default='SOME STRING', upload_to='audio_stories/',null=True, validators=[validate_file_extension_audio])
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('story-detail', kwargs={'pk': self.pk})
serializers.py(Django)
class StorySerializer(serializers.ModelSerializer):
class Meta:
model = Story
fields = '__all__'
MultiPartParser用于传递文件和数据。
api.py(Django)
class StoryViewSet(viewsets.ModelViewSet) (Django):
serializer_class = StorySerializer
parser_classes = (MultipartJsonParser, parsers.JSONParser)
queryset = Story.objects.all()
permission_classes = [
permissions.IsAuthenticated
]
def perform_create(self, serializer):
serializer.save(author=self.request.user)
utils.py(Django)
class MultipartJsonParser(parsers.MultiPartParser):
def parse(self, stream, media_type=None, parser_context=None):
result = super().parse(
stream,
media_type=media_type,
parser_context=parser_context
)
data = {}
# find the data field and parse it
data = json.loads(result.data["data"])
qdict = QueryDict('', mutable=True)
qdict.update(data)
return parsers.DataAndFiles(qdict, result.files)
在操作story.js(实际)
import axios from "axios";
import { tokenConfig } from './auth';
import { createMessage, returnErrors } from "./messages";
import {ADD_STORY} from "./types";
const apiBase = "http://localhost:8000/api";
export const addStory = story => (dispatch, getState) => {
axios
.post(apiBase +"/story/", story, tokenConfig(getState))
.then(res => {
dispatch(createMessage({ addStory: "Story Added" }));
dispatch({
type: ADD_STORY,
payload: res.data
});
})
.catch(err =>
dispatch(returnErrors(err.response.data, err.response.status))
);
};
在组件中create_story.js(反应)
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { addStory } from "../../actions/story";
export class CreateStory extends Component {
state = {
title: "",
content:""
};
static propTypes = {
addStory: PropTypes.func.isRequired
};
onChange = e => this.setState({ [e.target.name]: e.target.value });
onSubmit = e => {
e.preventDefault();
const { title,content, audio} = this.state;
const story = { title, content, audio};
this.props.addStory(story);
this.setState({
title: "",
content:"",
audio:""
});
};
render() {
const {title, content, audio} = this.state;
return (
<div className="card card-body mt-4 mb-4">
<h2>Add Story</h2>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Title</label>
<input
className="form-control"
type="text"
name="title"
onChange={this.onChange}
value={title}
/>
</div>
<div className="form-group">
<label>Content</label>
<input
className="form-control"
type="text"
name="content"
onChange={this.onChange}
value={content}
/>
</div>
<div className="form-group">
<label>Audio</label>
<input
className="form-control"
type="file"
name="audio"
onChange={this.onChange}
value={audio}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">
Submit
</button>
</div>
</form>
</div>
);
}
}
export default connect(
null,
{ addStory }
)(CreateStory);
我在查找代码中的错误时遇到麻烦。我假设react表单没有提供正确的数据格式,即formdata。但是我不知道该如何改变我们。没有文件上传,我就能够成功地将数据传递到数据库中。
非常感谢。
答案 0 :(得分:0)
您在onChange
中的create_story.js
函数未收集文件。您可能需要将该函数重新格式化为以下格式:
onChange = (e) => {
if(e.target.name === 'audio') {
this.setState({
[e.target.name]: e.target.files[0]
}, () => console.log(this.state.audio))
} else {
this.setState({
[e.target.name]: e.target.value
}, () => console.log(this.state))
}
}