Django REST + React + Redux 上传文件

2019-08-20 11:28:34 浏览数 (1)

环境

后端:

  • Django==2.0.5
  • djangorestframework==3.8.2

前端:

  • "react": "^16.3.2"
  • "react-redux": "^5.0.7"
  • "redux": "^4.0.0"

后端

Models:

代码语言:javascript复制
class Supervise(models.Model):
    ...
    photo = models.ImageField(upload_to='media/supervise/',null=True,blank=True) # 照片附件
    ...

Serializers:

代码语言:javascript复制
class SuperviseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Supervise
        fields = (...,'photo',...)

Views:

代码语言:javascript复制
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:

代码语言:javascript复制
# 子URL文件
urlpatterns = [
        ...
        url(r'supervises/$', views.SuperviseList.as_view()),
        ...
]
# 父URL文件
...
if settings.DEBUG:
    urlpatterns  = static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT) # 没有这个,调试模式下图片不显示
...

Settings:

代码语言:javascript复制
...
MEDIA_ROOT = '/home/user/projects/project/back/'
MEDIA_URL = '/'
...

前端

Actions:

代码语言:javascript复制
...
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:

代码语言:javascript复制
...
export default function(state=initialState, action) {
    switch(action.type) {
        ...
        case NEW_SUPERVISE:
            return {
                ...state,
                item: action.payload
            };
        ...
        default:
            return state;         
    }
}
...

Component:

代码语言:javascript复制
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));

0 人点赞