环境
后端:
- Django==2.0.5
- djangorestframework==3.8.2
前端:
- "react": "^16.3.2"
- "react-redux": "^5.0.7"
- "redux": "^4.0.0"
后端
Models:
class Supervise(models.Model):
...
photo = models.ImageField(upload_to='media/supervise/',null=True,blank=True) # 照片附件
...
Serializers:
class SuperviseSerializer(serializers.ModelSerializer):
class Meta:
model = Supervise
fields = (...,'photo',...)
Views:
class SuperviseList(generics.ListCreateAPIView):
queryset = Supervise.objects.all().order_by('-ddate')
serializer_class = SuperviseSerializer
permission_classes = (IsOwnerOrReadOnly,)
def perform_create(self, serializer):
user = self.request.user
if user.is_authenticated:
photo = self.request.data.get('photo')
serializer.save(creater=user,photo=photo)
URLS:
# 子URL文件
urlpatterns = [
...
url(r'supervises/$', views.SuperviseList.as_view()),
...
]
# 父URL文件
...
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT) # 没有这个,调试模式下图片不显示
...
Settings:
...
MEDIA_ROOT = '/home/user/projects/project/back/'
MEDIA_URL = '/'
...
前端
Actions:
...
export const createSupervise = (superviseData, token) => dispatch => {
var formData = new FormData();
for (var name in superviseData) {
if (name === 'photo') {
if (superviseData['photo'] !== null) { /*此处要考虑photo字段为空的情况*/
formData.append(name, superviseData[name]);
}
} else {
formData.append(name, superviseData[name]);
}
}
fetch(UURL+'supervise/supervises/',{
method: 'POST',
headers: {
'Authorization': 'JWT ' + token,
},
body: formData
})
.then(res=>res.json())
.then(supervise=>
dispatch({
type: NEW_SUPERVISE,
payload: supervise
})
);
}
...
Reducers:
...
export default function(state=initialState, action) {
switch(action.type) {
...
case NEW_SUPERVISE:
return {
...state,
item: action.payload
};
...
default:
return state;
}
}
...
Component:
class SuperviseForm extends Component {
constructor(props) {
super(props);
this.state = {
...
photo: null,
...
}
...
this.onSubmit = this.onSubmit.bind(this);
this.onPhotoChange = this.onPhotoChange.bind(this);
}
...
onPhotoChange(e) {
this.setState({photo: e.target.files[0]})
}
onSubmit(e) {
e.preventDefault();
const supervise = {
...,
photo: this.state.photo,
}
if (!this.state.is_edit_mode) {
this.props.createSupervise(supervise, this.props.userinfo.token);
} else {
...
}
}
render() {
return (
<form onSubmit={this.onSubmit} className="form-element" encType="multipart/form-data">
...
<label htmlFor="photo">附件</label>
<input type="file" id="photo" name="photo" onChange={this.onPhotoChange} />
<img src = {this.state.photo} alt="" />
<hr />
<button type="submit">保存</button>
</form>
...
)
}
}
SuperviseForm.propsTypes = {
createSupervise: propsTypes.func.isRequired,
...
}
const mapStateToProps = state => ({
...
})
export default withRouter(
connect(mapStateToProps,{ createSupervise, ... })(SuperviseForm));