2009-12-09 75 views
18

我看到很多用Django應用程序的用戶上傳圖片時會自動調整圖片大小。對某些情況來說這很好,但我不想這樣做。相反,我只是想強制用戶上傳一個已經合適大小的文件。在django中驗證圖片大小admin

我想要一個ImageField,我強制用戶上傳100x200的圖像。如果他們上傳的圖片大小不正確,我希望管理員表單返回無效狀態。我也希望能夠爲高寬比做同樣的事情。我想強制用戶上傳16:9的圖像,並拒絕任何不符合的上傳。

我已經知道如何獲取圖像的寬度和高度,但是我不能在服務器端執行該操作,直到圖像已經上傳並且表單成功提交。如果可能的話,我怎麼能早點檢查一下?

回答

45

正確的位置是在表單驗證過程中。
一個簡單的例子(將編輯/更多的信息整合後):

from django.core.files.images import get_image_dimensions 
from django.contrib import admin 
from django import forms 

class myForm(forms.ModelForm): 
    class Meta: 
     model = myModel 
    def clean_picture(self): 
     picture = self.cleaned_data.get("picture") 
     if not picture: 
      raise forms.ValidationError("No image!") 
     else: 
      w, h = get_image_dimensions(picture) 
      if w != 100: 
       raise forms.ValidationError("The image is %i pixel wide. It's supposed to be 100px" % w) 
      if h != 200: 
       raise forms.ValidationError("The image is %i pixel high. It's supposed to be 200px" % h) 
     return picture 

class MyAdmin(admin.ModelAdmin): 
    form = myForm 

admin.site.register(Example, MyAdmin) 
+0

我是太慢了,這裏的相關鏈接: http://docs.djangoproject.com/en/dev/ref/forms/validation/#清潔特定字段屬性 – monkut

+1

儘管此解決方案很酷以供參考,但OP表示他希望在提交表單之前檢查圖像的尺寸。所以它必須是客戶端。還是我誤解了他的最後一段? – cethegeek

+0

只要在模型保存之前,我並不一定表示提交表單之前。 – Apreche

0

這可能是一個欺騙/非常類似於這樣的問題:

Using jQuery, Restricting File Size Before Uploading

我不認爲有一種方法可以按照你想要的方式來完成。阿戈解決辦法是去...

編輯方式:在一個有關使用閃光燈做鏈接的SO問題會談的答案。所以,儘管可能會使用其他技術,但我不認爲你可以用直接的javascript來做到這一點。

+0

另一種可能的技術可能是Java applet。我見過不少上傳者用這種方式解決了這個問題。如果您真的想要允許大量上傳,這也很有用。 – Agos

2

使用此功能在你的模型文件,

from django.core.exceptions import ValidationError 

    def validate_image(fieldfile_obj): 
      filesize = fieldfile_obj.file.size 
      megabyte_limit = 2.0 
      if filesize > megabyte_limit*1024*1024: 
       raise ValidationError("Max file size is %sMB" % str(megabyte_limit)) 

    class Company(models.Model): 
     logo = models.ImageField("Logo", upload_to=upload_logo_to,validators=[validate_image], blank=True, null=True,help_text='Maximum file size allowed is 2Mb') 
+0

這不起作用。簡單地返回'*** FileNotFoundError:[Errno 2]沒有這樣的文件或目錄:'/ srv/www/media/80329e39-5c5c-4e79- 8e32-51087ae00f6a''。也許它可以處理Django不保存爲'InMemoryUploadedFile'對象的文件,它們位於'/ tmp'中或類似於實際文件的位置。但是,我沒有測試過。 – Bryson