django - 如何使用 django modelform 通过复制/粘贴上传图像?

标签 django google-apps-script django-forms modelform

我是 django 的新手,正在尝试将 google apps 脚本 (GAS) webapp 迁移到 django。

我在 google 网站上的一个功能是从剪贴板捕获粘贴的图像并通过表单提交。这是通过表单中的隐藏字段完成的:

<input type="hidden" name="summaryImage" id='summaryImage' value=''>

然后我捕获粘贴事件来填充这个隐藏的表单字段

/* Handle paste events */
function pasteHandler(e) {
   if (e.clipboardData) {
      // Get the items from the clipboard
      var items = e.clipboardData.items;
      if (items) {
         // Loop through all items, looking for any kind of image
         for (var i = 0; i < items.length; i++) {
            if (items[i].type.indexOf("image") !== -1) {
               // We need to represent the image as a file,
               var blob = items[i].getAsFile();
               var URLObj = window.URL || window.webkitURL;
               var source = URLObj.createObjectURL(blob);
               var reader = new FileReader();
               reader.onload = function(e) {
                 document.getElementById("summaryImage").value= reader.result;
               }
               reader.readAsDataURL(blob);
            } 
          }
      }
   } 
}

当通过 google 提交上述表单时,可以在服务器端 google apps 脚本 (GAS) 从表单中的 summaryImage 字段解析,如下所示:

var splitBase = form.summaryImage.split(','),
var type = splitBase[0].split(';')[0].replace('data:','');
var byteCharacters = Utilities.base64Decode(splitBase[1]);
var blob = Utilities.newBlob(byteCharacters, type);

现在,在 Django 中,我无法复制它。我在 models.py 中创建了一个带有 ImageField 的模型:

...
image = models.ImageField(blank=True, null=True, verbose_name='Image')
...

并在 forms.py 中将小部件设置为 HiddenInput()

class MyForm(forms.ModelForm):

    class Meta:
        model = myModel
        fields = '__all__'
        widgets = {
            'image': forms.HiddenInput()
        }
    ...

甚至在捕获粘贴时,我将其设置为这个隐藏的图像字段:

document.getElementById("id_image").value= reader.result;

但后来我无法提交表单,收到一条错误消息:

(Hidden field image) No file was submitted. Check the encoding type on the form.

我搜索了很多但找不到任何关于在 django 中从剪贴板捕获粘贴图像的提及。这甚至可行吗?

最佳答案

感谢@allcaps 的建议,我找到了解决方案。

基本上我在我的模型中保留了 ImageField(图像),并分配了一个自定义小部件以仅显示其 ID id_image。然后在表单中添加一个隐藏的输入字段image_container来接收粘贴的数据。表单的保存功能被覆盖以创建文件并将其保存回 ImageField。

class PictureWidget(forms.widgets.Widget):
    def render(self, name, value, attrs=None):
        if str(value) == '':
            html1 = "<img id='id_image' style='display:block' class='rounded float-left d-block'/>"
        else:
            html1 = "<img id='id_image' style='display:block' class='rounded float-left d-block' src='" + settings.MEDIA_URL + str(value) + "'/>"
        return mark_safe(html1)

class MyForm(forms.ModelForm):

    image_container = forms.CharField(required=False, widget=forms.HiddenInput())
    class Meta:
        model = MYMODEL
        fields = '__all__'
        widgets = {
            'image': PictureWidget(),
        }
    def save(self, commit=True):
        # check image_container data
        self.instance.image.delete(False)
        imgdata = self.cleaned_data['image_container'].split(',')
        try:
            ftype = imgdata[0].split(';')[0].split('/')[1]
            fname = slugify(self.instance.title)
            self.instance.image.save('path/%s.%s' % (fname, ftype), ContentFile(imgdata[1].decode("base64")))
        except:
            pass
        return super(MyForm, self).save(commit=commit)

关于django - 如何使用 django modelform 通过复制/粘贴上传图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43481931/

相关文章:

python - 需要POST类型时请求类型为GET

django - 如何在 Django 中更改表对象名称?

python - 编辑ModelFormSet中的相关对象

google-apps-script - Google Web 应用程序脚本不断要求用户登录?

python - Django 和 Python : Format a FloatField in django form by adding separators

django - 将表单添加到 django-flatpages

python - Django 表单字段标签翻译

python - Django 从 ImageField 下载图像

javascript - 获取工作表的范围,直到包含数据的最后一个单元格

javascript - 如何使用 .map() 方法将值从一页放置到另一页,并使用数据作为下一页的坐标