我需要验证上传文件的文件类型,并且只允许pdf,普通测试和MS word文件。这是我的模型和带验证功能的表单。但是,即使没有扩展名,我也可以上传文件。
class Section(models.Model):
content = models.FileField(upload_to="documents")
class SectionForm(forms.ModelForm):
class Meta:
model = Section
FILE_EXT_WHITELIST = ['pdf','text','msword']
def clean_content(self):
content = self.cleaned_data['content']
if content:
file_type = content.content_type.split('/')[0]
print file_type
if len(content.name.split('.')) == 1:
raise forms.ValidationError("File type is not supported.")
if content.name.split('.')[-1] in self.FILE_EXT_WHITELIST:
return content
else:
raise forms.ValidationError("Only '.txt' and '.pdf' files are allowed.")
这是视图,
def section_update(request, object_id):
section = models.Section.objects.get(pk=object_id)
if 'content' in request.FILES:
if request.FILES['content'].name.split('.')[-1] == "pdf":
content_file = ContentFile(request.FILES['content'].read())
content_type = "pdf"
section.content.save("test"+'.'+content_type , content_file)
section.save()
在我看来,我只是从request.FILE
保存文件。我想虽然save()它会调用clean_content并进行内容类型验证。我想,clean_content根本不需要验证。
答案 0 :(得分:5)
您的方法无效:作为攻击者,我可以简单地伪造HTML标头,向您发送mime类型为text/plain
的任何内容。
正确的解决方案是在Unix上使用像file(1)
这样的工具来检查文件的内容以确定它是什么。请注意,没有什么好方法可以知道某些内容是否真的是纯文本。如果文件以16位Unicode保存,则“纯文本”甚至可以包含0个字节。
有关如何执行此操作的选项,请参阅此问题:How to find the mime type of a file in python?
答案 1 :(得分:1)
您可以使用 python-magic
System.setProperty("logging.file", "C:\\outputFolder\\fileName2.log");
答案 2 :(得分:0)
这是一个老问题,但对于后来的用户来说,评论中提到的主要问题是为什么不进行字段验证,并且如调用 is_valid() 时执行 django 文档字段验证中所述。因此,必须使用以下内容来激活字段验证:
section = models.Section.objects.get(pk=object_id)
if request.method == 'POST':
form = SectionForm(request.POST, request.FILES)
if form.is_valid:
do_something_with_form
<块引用>
表单验证在数据被清理时发生。如果您想自定义此过程,可以在多个地方进行更改,每个地方都有不同的用途。在表单处理期间运行三种类型的清洁方法。这些通常在您调用表单上的 is_valid() 方法时执行