问题是,我有一个包含文件字段的Django表单,即:
photo = forms.FileField(help_text="Please attach a photo", required=False)
如果表单有效,则“文件”字段将被绑定并正确保存。 问题是当用户填写所有表单但未验证时:所选文件的路径消失。
因此,如果用户没有意识到这一点,他/她会修复其他字段错误并再次提交 - 这次没有照片。
以防万一,表单在视图中创建如下:
ProfileForm(request.POST or None, request.FILES or None)
,HTML是:
<div id="uniform-id_photo" class="uploader">
<input id="id_photo" class="clearablefileinput" type="file" name="photo" size="19" style="opacity: 0;">
<span class="filename" style="-moz-user-select: none;">No file selected</span>
<span class="action" style="-moz-user-select: none;">Choose File</span>
</div>
之前有没有人遇到过同样的问题?对解决方案的任何想法? :)
谢谢!
答案 0 :(得分:26)
不幸的是,这是浏览器强加的问题(实际上是一种安全功能),因此无法解决。浏览器不允许您为文件输入指定初始值,并且没有任何东西可以解决这个问题。
原因是,如果一个网站可以这样做,它会打开一个矢量,允许任何网站通过猜测文件路径窃取你的计算机上的任何文件 - 他们可能只是在后台运行的脚本运行将有趣的文件发回服务器。
唯一的解决方法是将上传的文件实际保存在服务器上,无论表单是否验证,然后当您将表单和错误呈现给用户时,表明您已收到文件并且他们应该只填写在那个领域取代它。
答案 1 :(得分:0)
我写了一些解决方案:
class CustomClearableFileInput(ClearableFileInput):
def render(self, name, value, attrs=None):
if len(<YourModel>.objects.filter(id=self.form_instance_id))>0:
file = <YourModel>.objects.get(id=self.form_instance_id).<yourField>
else:
file = ''
substitutions = {
'initial_text': self.initial_text,
'input_text': self.input_text,
'clear_template': '',
'clear_checkbox_label': self.clear_checkbox_label,
}
template = '%(input)s'
substitutions['input'] = super(ClearableFileInput, self).render(name, value, attrs)
self.template_with_initial = ('<p class="file-upload">%s</p>'
% self.template_with_initial)
self.template_with_clear = ('<span class="clearable-file-input">%s</span>'
% self.template_with_clear)
if value and hasattr(value, "url"):
template = self.template_with_initial
substitutions['initial'] = format_html(self.url_markup_template,
value.url,
force_text(value))
if not self.is_required:
checkbox_name = self.clear_checkbox_name(name)
checkbox_id = self.clear_checkbox_id(checkbox_name)
substitutions['clear_checkbox_name'] = conditional_escape(checkbox_name)
substitutions['clear_checkbox_id'] = conditional_escape(checkbox_id)
substitutions['clear'] = CheckboxInput().render(checkbox_name, False, attrs={'id': checkbox_id})
substitutions['clear_template'] = self.template_with_clear % substitutions
url = '' if file == '' else file.url
else:
template = self.template_with_initial
substitutions['initial'] = format_html(self.url_markup_template,
url,
force_text(file))
if not self.is_required:
checkbox_name = self.clear_checkbox_name(name)
checkbox_id = self.clear_checkbox_id(checkbox_name)
substitutions['clear_checkbox_name'] = conditional_escape(checkbox_name)
substitutions['clear_checkbox_id'] = conditional_escape(checkbox_id)
if fav == '':
substitutions['clear'] = CheckboxInput().render(checkbox_name, False, attrs={'id': checkbox_id, 'disabled': 'disabled'})
else:
substitutions['clear'] = CheckboxInput().render(checkbox_name, False, attrs={'id': checkbox_id})
substitutions['clear_template'] = self.template_with_clear % substitutions
return mark_safe(template % substitutions)
然后在你的表格中你必须写:
class <YourModel>Form(ModelForm):
class Meta:
model = <YourModel>
fields = '__all__'
widgets= {'<YourField>': CustomClearableFileInput}
def __init__(self, *args, **kwargs):
super(OperatorSettingsForm, self).__init__(*args, **kwargs)
self.fields['<YourField>'].widget.form_instance_id = self.instance.id
它对我有用。我想你也没问题:)