专栏首页fanzhh的技术笔记Django REST + React + Redux 上传文件

Django REST + React + Redux 上传文件

环境

后端:

  • 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));

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • React人机验证控件

    在使用React做前端,用户注册页面因为要短信验证,短信服务商要求加人机验证,于是我找到了 react-captcha-generator。

    fanzhh
  • 使用Sqlite3+Express.js+React实现在线答题(下)

    在使用Sqlite3+Express.js+React实现在线答题(上)中,我们将题目数据从word文件转为txt格式并导入到sqlite3中,使用Expres...

    fanzhh
  • 以 React 的方式思考

    React 很棒的一点是创建应用中引导你思考的过程。这篇文档中,我们将通过运用React创建一个产品搜索列表,来引导你熟悉这个思考过程。

    fanzhh
  • 面试题:Java中this和super关键字的底层实现原理

    今天,我们就一起来讨论一个这个网友遇到的面试题,Java 中 this 和 super 关键字的底层实现原理!

    业余草
  • 数据结构于JS也可以成为CP(三)栈

    Hello小伙伴们大家好,今天要为大家带来的是栈,这是数据结构中常用到的一种结构。它和列表有一点相似,又有些不同。相对于列表来说,栈更加高效,为啥呢,因为栈只能...

    萌兔IT
  • 雪花代码

    <style type="text/css"> .large-header {background: #333;} </style> <div id="la...

    似水的流年
  • Flutter基础widgets教程-DataTable篇

    青年码农
  • 修炼内功之JavaScript设计模式(三)

    工作时间久了,自然对软件系统产生自己的思考,还会面临职业生涯的一个挑战。要不要成为一个技术负责人?

    童欧巴
  • 三、Vue 的一些语法样例

    其实vue 的语法在官网上都有详细的讲解和例子,我这里就不多做什么说明,只是把自己学习这些语法是练习的例子贴出来。另外官网上的例子是一个个的html文件。我这里...

    程序员爱酸奶
  • Flutter基础widgets教程-DataTable篇

    青年码农

扫码关注云+社区

领取腾讯云代金券