django Rest框架不接受blob图片文件(不允许文件扩展名“”)

dim*_*nov 4 django blob file-upload django-models django-rest-framework

我正在尝试通过发出包含 png blob 图像文件的multipart/form-data put 请求(使用 axios 从我的 vue 前端)来更新用户配置文件。我收到一条错误消息:不允许文件扩展名 \xe2\x80\x9c\xe2\x80\x9d。\n这是用户配置文件模型上的文件字段:

\n
    profile_picture = models.FileField(\n    _("Profile Pictures"),\n    upload_to="profile_picture",\n    max_length=100,\n    blank=True,\n    null=True,\n)\n
Run Code Online (Sandbox Code Playgroud)\n

这些是我在用户配置文件模型中用于保存和更新模型的信号。

\n
@receiver(post_save, sender=User)\ndef create_user_profile(sender, instance, created, **kwargs):\n    if created:\n        UserProfile.objects.create(user=instance)\n\n\n@receiver(post_save, sender=User)\ndef save_user_profile(sender, instance, **kwargs):\n    instance.profile.save()\n
Run Code Online (Sandbox Code Playgroud)\n

我认为这可能是因为这些或用户配置文件模型的其他特定内容导致了错误,因为在另一个模型上,文件上传按预期工作,尽管我正在发布帖子而不是放置请求。用户配置文件模型通过一对一字段连接到用户。

\n

我的序列化器或视图中没有什么特别的可能导致该错误。

\n

我不知道我能做些什么来解决这个问题。感谢您的所有建议。如果您需要任何其他信息,请随时询问。

\n

该图像是随 put 请求发送的表单数据...可能有问题:

\n

1

\n

发出请求的axios代码:

\n
import axios from \'axios\'\n\nconst apiClient = axios.create({\n  baseURL: `http://127.0.0.1:8000/`,\n  withCredentials: false,\n  headers: {\n    Accept: \'application/json\',\n    \'Content-Type\': \'multipart/form-data\'\n  }\n})\n\nexport default {\n  updateUser(pk, params) {\n    return apiClient.put(\'/users/\' + pk + \'/\', params)\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是我裁剪图片的部分,它是一个 dataURI,然后我将其转换为 blob 以发送到后端服务器:

\n
\n  methods: {\n    crop() {\n      const { coordinates, canvas } = this.$refs.cropper.getResult()\n      this.coordinates = coordinates\n      this.file = canvas.toDataURL()\n    },\n    uploadImage(event) {\n      const input = event.target\n      if (input.files && input.files[0]) {\n        // create a new FileReader to read this image and convert to base64 format\n        const reader = new FileReader()\n        // Define a callback function to run, when FileReader finishes its job\n        reader.onload = (e) => {\n          // Read image as base64 and set to imageData\n          this.file = e.target.result\n        }\n        // Start the reader job - read file as a data url (base64 format)\n        reader.readAsDataURL(input.files[0])\n      }\n    },\n    dataURItoBlob(dataURI) {\n      // convert base64 to raw binary data held in a string\n      const byteString = atob(dataURI.split(\',\')[1])\n\n      // separate out the mime component\n      const mimeString = dataURI\n        .split(\',\')[0]\n        .split(\':\')[1]\n        .split(\';\')[0]\n\n      // write the bytes of the string to an ArrayBuffer\n      const ab = new ArrayBuffer(byteString.length)\n      const ia = new Uint8Array(ab)\n      for (let i = 0; i < byteString.length; i++) {\n        ia[i] = byteString.charCodeAt(i)\n      }\n      return new Blob([ab], { type: mimeString })\n    },\n    async updateUser() {\n      this.crop()\n      delete this.user.password2\n      const formData = new FormData()\n      if (this.file)\n        formData.append(\'profile_picture\', this.dataURItoBlob(this.file))\n      if (this.user.username) formData.append(\'username\', this.user.username)\n      else formData.append(\'username\', this.$auth.user.username)\n      if (this.user.email) formData.append(\'email\', this.user.email)\n      if (this.user.bio) formData.append(\'bio\', this.user.bio)\n      if (this.user.password) formData.append(\'password\', this.user.password)\n      else formData.append(\'password\', this.$auth.user.password)\n\n      await UserFormService.updateUser(this.$auth.user.pk, formData)\n\n      await this.$store.dispatch(\'users/updateUser\', this.user)\n      this.$auth.setUser(this.$store.state.users.user)\n      this.$router.push(\'/users/me\')\n\n
Run Code Online (Sandbox Code Playgroud)\n

Mus*_*usa 6

由于您的端点需要特定的文件扩展名,因此您必须手动设置它,因为 blob 没有文件名,并且文件上传的默认值是blob. FormData.append中有第三个可选参数来设置文件名

formData.append('profile_picture', this.dataURItoBlob(this.file), 'some_filename.valid_extension')
Run Code Online (Sandbox Code Playgroud)