2009-12-09 76 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