由于我想将fileupload限制为某些类型的audiofiles,我发现django片段http://djangosnippets.org/snippets/977/,它将文件上传限制为扩展名白名单中的文件:
class ExtFileField(forms.FileField):
"""
Same as forms.FileField, but you can specify a file extension whitelist.
>>> from django.core.files.uploadedfile import SimpleUploadedFile
>>>
>>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
>>>
>>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
>>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
>>>
>>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
Traceback (most recent call last):
...
ValidationError: [u'Not allowed filetype!']
"""
def __init__(self, *args, **kwargs):
ext_whitelist = kwargs.pop("ext_whitelist")
self.ext_whitelist = [i.lower() for i in ext_whitelist]
super(ExtFileField, self).__init__(*args, **kwargs)
def clean(self, *args, **kwargs):
data = super(ExtFileField, self).clean(*args, **kwargs)
filename = data.name
ext = os.path.splitext(filename)[1]
ext = ext.lower()
if ext not in self.ext_whitelist:
raise forms.ValidationError("Not allowed filetype!")
在我的表单中,我有一个标准的FileField,直到现在。上传文件,保存并完美运行。然后我像这样替换FileField
class NewItemForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(NewItemForm, self).__init__(*args, **kwargs)
self.fields['file']=ExtFileField(ext_whitelist=(".wav", ".aif", ".flac"))
class Meta:
model = Item
fields = ('file','name','meta1','tags')
当尝试上传不在白名单中的任何文件时,我收到错误消息“Not allowed filetype!”,这很好。但是当在白名单中上传文件时,我收到错误消息“此字段不能为空。”,我不明白。我只是怀疑它与我从模型中替换文件字段的方式有关。什么是正确的方法呢?
答案 0 :(得分:0)
覆盖模型表上字段的正确方法就是在类级别声明字段:
class NewItemForm(forms.ModelForm):
file = ExtFileField(ext_whitelist=(".wav", ".aif", ".flac"))
答案 1 :(得分:0)
在'clean'方法结束时,请确保返回数据,以便form.FileField的常规clean方法可以访问它。在您当前的实现中(直接来自代码段),forms.FileField clean方法将不会获取上传的文件。
我还需要调整我的方法,因为我有不需要的字段。因此,实现将无法尝试访问数据的name属性(因为数据为None)。
最后,您可以使用内容类型(下面未显示)执行相同类型的文件白名单,而不是检查扩展名,而是检查data.file.content_type与您将传递到字段构造函数的content_whitelist参数(与ext_whitelist一样。
def clean(self, *args, **kwargs):
data = super(ExtFileField, self).clean(*args, **kwargs)
if data:
filename = data.name
ext = os.path.splitext(filename)[1]
ext = ext.lower()
if ext not in self.ext_whitelist:
raise forms.ValidationError("Filetype '%s' not allowed for this field" % ext)
elif not data and self.required:
raise forms.ValidationError("Required file not found for %s" % self.label)
return data