如何在Django中检查上传的文件是否为有效图像

12
我在我的模型中有一个ImageField,以便用户可以上传图片。当用户提交上传表单时,我想验证所上传的文件是完全有效且可显示的图像。
我尝试使用PIL来验证图像是否真实,但使用了

from PIL import Image
Image.open(model.file)
Image.verify()
无论我提供哪个文件,它总是抛出异常。 有人知道一种简单的验证文件的方法吗?
4个回答

10

2
这是正确的,但它似乎不能自行完成所有操作。需要你在forms.py中设置表单以便进行验证。 - Zach Sugano
你是通过处理原始的POST数据来处理上传的吗? - e4c5
是的。我试图在我设置的视图方法中处理所有内容。我使用了表单系统以及is_valid()方法,这非常有效。 - Zach Sugano
很高兴它能够正常工作。Django表单绝对是正确的选择。 - e4c5
1
@Zach Sugano,你能提供一个来源证明ImageField验证只适用于Django表单吗?这将非常有帮助。我需要图像验证,但Django只是后端,所以不能使用他们的表单。 - M3RS

4
此外,您应该按以下方式使用verify():
from PIL import Image
im = Image.open(model.file)
im.verify()

1
我认为 Pillow 库在打开图像时会抛出异常,而不是需要在图像打开后进行验证。因此,如果图像无效,则第二行代码将抛出 "IOError" 异常。 - dphans
这就是Django的ImageField已经实现的功能。请参考源代码:https://github.com/django/django/blob/2ea3fb3e6386c43f124b542e92b817dbc227c76b/django/forms/fields.py#L634 - user3064538

2
你可以在将图像/数据插入到数据库或在任何需要使用时,使用“try, except”块来使用“Pillow”。以下是我提交支持表单的示例,“view.py”文件:

你可以使用“Pillow”和“try, except”块,在将图像/数据插入到数据库或在任何需要使用时使用它。以下是我提交支持表单的示例,“view.py”文件:
from PIL import Image
    
    if request.method=='POST':
       # check if attachment file is not empty inside try/except to pass django error.
        try:
            ticket_attachmet_image = request.FILES["q_attachment_image"]
        except:
            ticket_attachmet_image = None

       # check if uploaded image is valid (for example not video file ) .
        if not ticket_attachmet_image == None:
            try:
                Image.open(ticket_attachmet_image)
            except:
                messages.warning(request, 'sorry, your image is invalid')
                return redirect('your_url_name')

#完成。


你在这里发布了一个函数的代码,但没有展示函数本身。使用基于类的视图的人将无法理解如何实现它。 - Conor

0
if 'image' in request.FILES['image'].content_type:
    # Some code
else:
    # the file is not image

ImageField在表单不是由form.py创建时无法工作。

实际上,如果我们上传的文件不是图片,并将其保存在图像字段中,它不会引发任何错误,因此在保存之前必须检查文件的content_type


1
content_type 可以被操纵;你实际上是在信任用户发送正确的内容类型,这是不安全的。文件必须经过独立验证,以确保它们是正确的文件类型。来自 Django 文档:https://docs.djangoproject.com/en/4.0/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type - dKen
这个 "request.FILES" 是不是只适用于基于函数的视图?文档喜欢省略这样的细节。 - Conor
如果请求方法为POST且提交请求的<form>标签具有属性enctype="multipart/form-data",那么FILES才会包含数据。因此,在基于类的视图中,它将会包含POST方法中的数据;在基于函数的视图中,当请求方法为'POST'时它才会包含数据。@Conor - Amin Mir
谢谢,是的,我昨天才发现那些CreateView函数(我是Django新手)。 - Conor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接