Django:使用python-magic的模型中的文件字段验证

问题描述:

我有一个包含文件字段的模型。我想限制它到PDF文件。我在模型中写了干净的方法,因为我想检查管理员和shell级别模型的创建。但它不适用于模型清洁方法。然而形式干净的方法正在工作。Django:使用python-magic的模型中的文件字段验证

class mymodel(models.Model): 
    myfile = models.FileField() 

    def clean(): 
     mime = magic.from_buffer(self.myfile.read(), mime=True) 
     print mime 
     if not mime == 'application/pdf': 
      raise ValidationError('File must be a PDF document') 

class myform(forms.ModelForm): 
    class Meta: 
     model = mymodel 
     fields = '__all__' 

    def clean_myfile(self): 
     file = self.cleaned_data.get('myfile') 
     mime = magic.from_buffer(file.read(), mime=True) 
     print mime 
     if not mime == 'application/pdf': 
      raise forms.ValidationError('File must be a PDF document') 
     else: 
      return file 

如果我上传pdf,表单清理方法中的mime正确验证(打印'application/pdf')。但是模型清理方法不能验证。它将mime打印为'application/x-empty'。我在哪里做错了?

还有一个问题是,如果模型清理方法引发验证错误,它不会在窗体中显示为字段错误,但它显示为非字段错误。为什么这样 ?

由于您使用的表单验证你是不是要担心模型清洁方法

你已经在做正确的事情形式

def clean_file(self): 
     yourfile = self.cleaned_data.get("your_filename_on_template", False) 
     filetype = magic.from_buffer(yourfile.read()) 
     if not "application/pdf" in filetype: 
      raise ValidationError("File is not PDF.") 
     return yourfile 

如果你想使用模型清理可以让你的自己的验证

https://*.com/a/27916582/5518973

您正在使用服务器端的python-Django的验证,但JavaScript可以用于验证文件的客户端很好的方式side.For JavaScript的正则表达式验证就可以看出来这个答案

https://*.com/a/17067242/5518973

,或者如果你能够使用的插件,你可以使用jQuery验证插件

https://jqueryvalidation.org/

+1

不幸的是,上面的代码将无法正常工作。 'filetype'就像''PDF文档,版本1.3''。你需要赋值为'filetype = magic.from_buffer(yourfile.read(),mime = True)''以获得''application/pdf“' –

fields = '__all__' 

来自Django两勺的建议:Django 1.8的最佳实践

26.14请勿使用ModelForms.Meta.fields =“__ all __” - 这包括模型表单中的每个模型字段。这是一条捷径,也是一条危险的道路。 这与我们在第26.13节(不要使用ModelForms.Meta.exclude)中描述的内容非常相似,甚至与 自定义验证代码一起,将项目公开到基于表单的弥散分配 漏洞。我们主张尽可能避免使用这种技术,因为我们认为根本不可能捕获输入的所有变化。