如何使用django modelform通过复制/粘贴上传图像?
我是django的新手,正在尝试将google应用程序脚本(GAS)Web应用程序迁移到django 我在谷歌网站上的一个功能是从剪贴板上捕获粘贴的图像,然后通过表单提交。这是通过表单中的隐藏字段完成的:如何使用django modelform通过复制/粘贴上传图像?,django,google-apps-script,django-forms,modelform,Django,Google Apps Script,Django Forms,Modelform,我是django的新手,正在尝试将google应用程序脚本(GAS)Web应用程序迁移到django 我在谷歌网站上的一个功能是从剪贴板上捕获粘贴的图像,然后通过表单提交。这是通过表单中的隐藏字段完成的: <input type="hidden" name="summaryImage" id='summaryImage' value=''> 现在,在django,我很难复制这个。我在models.py中创建了一个带有ImageField的模型: ... image = models
<input type="hidden" name="summaryImage" id='summaryImage' value=''>
现在,在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;
但随后我无法提交表单,收到一条错误消息:
(隐藏字段图像)未提交任何文件。检查上的编码类型
表格
我搜索了很多,但找不到任何关于在django中从剪贴板捕获粘贴图像的内容。这是否可行 多亏@allcaps的建议,我想出了解决办法 基本上,我将ImageField(image)保存在模型中,并分配了一个自定义小部件,以仅显示id
id\u image
。然后在表单中添加一个隐藏的输入字段image\u container
,以接收粘贴的数据。表单的save函数将被重写以创建文件并将其保存回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)
class PictureWidget(forms.widgets.Widget):
def render(自身、名称、值、属性=无):
如果str(值)='':
html1=“”
返回标记_安全(html1)
类MyForm(forms.ModelForm):
image\u container=forms.CharField(必需=False,widget=forms.HiddenInput())
类元:
model=MYMODEL
字段='\uuuu所有\uuuu'
小部件={
“图像”:PictureWidget(),
}
def save(self,commit=True):
#检查图像容器数据
self.instance.image.delete(False)
imgdata=self.cleaned_数据['image_container'].split(','))
尝试:
ftype=imgdata[0]。拆分(“;”)[0]。拆分(“/”)[1]
fname=slugify(self.instance.title)
self.instance.image.save('path/%s.%s'(fname,ftype),ContentFile(imgdata[1]。decode(“base64”))
除:
通过
返回super(MyForm,self).save(commit=commit)
在html中,输入类型是隐藏的,而不是图像。我想Django表单应该有一个CharField来接受粘贴的数据。在form clean and save方法中,您可以将该字符串数据转换为文件对象,并使用该对象填充ImageField。@allcaps谢谢!!它似乎确实有效,并将数据捕获为字符串。看起来是这样的:数据:image/png;base64,Ivborw0Kggoaaaansuhueugaaabuaawcayaaavg9c4aaaamuleqvridwp8///fwyqayyqmwc2btrq6ofqajiohimvq2a0sve5qbkygebdiekqc6hwqoznwikwaaabjru5erkjggg=@allcaps,但我想需要一个更大的字段来保存图像,CharField maxlength是不够的。我会试试textarea。是否有更好的方法/字段类型捕获此数据?否,将charfield添加到表单中,而不是添加到模型中。从charfield上的表单文档:验证最大长度或最小长度(如果提供)。否则,所有输入都有效。
。因此,您不需要文本区域。
document.getElementById("id_image").value= reader.result;
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)