天天看点

Vue, Django 实现上传文件

研究了一整天,踩了无数坑,终于完成了。。以下代码可以做到在vue前端中得到form中的图片(也可以是个其他file),并且通过Django后端保存在本地,并在数据库中存取图片的路径:

Django setting中配置

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') 
           

Django views.py

class SignupView(APIView):
    def post(self, request, *args, **kwargs):
        name = request.data.get('name')
        image = request.FILES['image']
        image_path = os.path.join(settings.MEDIA_ROOT, image_name)
        #在没有目录路径时创建一个
        try:
            os.mkdir(settings.MEDIA_ROOT)
        except Exception:
            pass
        #将文件保存在本地
        f = open(image_path,'wb')
        for i in onecard.chunks():
            f.write(i)
        f.close()
        # 创建用户
        try:
            UserModel.objects.create(name=name,image=image_name)
        except Exception as e:
            # logger.info("[Users] Fail to create user!\n", e)
            response['success']='0'
        return Response(response)
           

Vue(用了bootstrap5)

<template>
    <div class="container" style="margin-top:20px">
      <form @submit.prevent="submitSignup" >
        <div class="mb-3">
          <label for="signup_name" class="form-label">* 姓名 Name</label>
          <input
            type="text"
            class="form-control"
            id="signup_name"
            placeholder="常用名"
            v-model="name"
          />
        </div>
        
        <div class="mb-3">
          <label for="image" class="form-label">Image</label>
          <input
            class="form-control"
            type="file"
            id="image"
            aria-describedby="imgHelpBlock"
          />
          <div
            id="imgHelpBlock"
            class="form-text"
            style="display:"
          >请上传图片</div>
        </div>
        
        <button class="btn btn-primary" style="margin-top:20px">Submit</button>
      </form>
    </div>
</template>

<script>
import axios from "axios";

export default {
  name: "Signup",
  data() {
    return {
      name: "",
      
    };
  },
  components: {},
  methods: {
    submitSignup() {
      //将数据放入formdata
        var form_data = new FormData();
        var image = document.getElementById("image").files[0];
        form_data.append('name', this.name);
        form_data.append('image', image, image.name);
    //这个headers和content-type很重要,我就是没有这个卡在这一整天
      axios
        .post("/users/signup", form_data,{headers: {
        'Content-Type': 'multipart/form-data'
    })
        .then((response) => {
          console.log("response:" );
        })
        .catch((error) => {
          console.log(error);
        });
      }
    },
  },
};
</script>
           

继续阅读