2016-10-01 49 views
2

我有一個包含文件字段的模型。我想限制它到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'。我在哪裏做錯了?

還有一個問題是,如果模型清理方法引發驗證錯誤,它不會在窗體中顯示爲字段錯誤,但它顯示爲非字段錯誤。爲什麼這樣 ?

回答

1

由於您使用的表單驗證你是不是要擔心模型清潔方法

你已經在做正確的事情形式

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://stackoverflow.com/a/27916582/5518973

您正在使用服務器端的python-Django的驗證,但JavaScript可以用於驗證文件的客戶端很好的方式side.For JavaScript的正則表達式驗證就可以看出來這個答案

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

,或者如果你能夠使用的插件,你可以使用jQuery驗證插件

https://jqueryvalidation.org/

+1

不幸的是,上面的代碼將無法正常工作。 'filetype'就像''PDF文檔,版本1.3''。你需要賦值爲'filetype = magic.from_buffer(yourfile.read(),mime = True)''以獲得''application/pdf「' –

0
fields = '__all__' 

來自Django兩勺的建議:Django 1.8的最佳實踐

26.14請勿使用ModelForms.Meta.fields =「__ all __」 - 這包括模型表單中的每個模型字段。這是一條捷徑,也是一條危險的道路。 這與我們在第26.13節(不要使用ModelForms.Meta.exclude)中描述的內容非常相似,甚至與 自定義驗證代碼一起,將項目公開到基於表單的彌散分配 漏洞。我們主張儘可能避免使用這種技術,因爲我們認爲根本不可能捕獲輸入的所有變化。

相關問題