【问题标题】:Max image size on file upload文件上传时的最大图像大小
【发布时间】:2011-09-05 22:22:26
【问题描述】:

我的表单中有一个 ImageField。我将如何强制执行最小/最大文件大小,例如 --

image = forms.ImageField(max_size = 2MB) 

image = forms.ImageField(min_size = 100k)

谢谢。

【问题讨论】:

标签: django image-processing django-forms


【解决方案1】:

基本上这是Django File upload size limit的副本

你有两个选择:

  1. 在 Django 中使用验证来检查上传文件的大小。这种方法的问题是文件必须在验证之前完全上传。这意味着如果有人上传了一个 1TB 的文件,您可能会在用户收到表单错误之前用完硬盘空间。

  2. 配置 Web 服务器以限制允许的上传正文大小。例如如果使用 Apache,请设置 LimitRequestBody 设置。这意味着如果用户尝试上传太多内容,他们将在 Apache 中获得可配置的错误页面

正如@pastylegs 在 cmets 中所说,将两者结合使用可能是最好的方法。假设您想要最大 5MB,也许在 Web 服务器级别强制执行 20MB 限制,在 Django 级别强制执行 5MB 限制。 20MB 的限制可以为恶意用户提供一些保护,而 Django 中的 5MB 限制提供了良好的用户体验。

【讨论】:

  • 两者结合可能是个好主意。通过 apache/nginx 等(可能 50mb)将所有上传限制在合理的范围内,然后在应用程序级别使其更具体
  • @pastylegs 我同意,这也是我会采取的方法。
【解决方案2】:

models.py

class Product(models.Model):
    image = models.ImageField(upload_to="/a/b/c/")

forms.py

class ProductForm(forms.ModelForm):
    # Add some custom validation to our image field
    def clean_image(self):
        image = self.cleaned_data.get('image', False)
        if image:
            if image._size > 4*1024*1024:
                raise ValidationError("Image file too large ( > 4mb )")
            return image
        else:
            raise ValidationError("Couldn't read uploaded image")

【讨论】:

  • forms.py 代码的第 4 行后面不应该有冒号,但它不会让我进行少于 6 个字符的更改。如果您要复制和粘贴此代码,请小心(而不是您应该复制+粘贴任何代码)。
  • 等等,这个是先上传整张图片还是先上传?在此验证发生之前,http 服务器(即 nginx)会不会将其捕获为 413?
  • 只有在文件完全上传到服务器后,Django才会检查文件限制大小条件。所以为了避免不必要的流量使用,你需要实现client检查或apache检查。
  • 应该是.size 而不是._size
【解决方案3】:

这是我在 stackoverflow 上的这个问题的变体中没有看到的另一个选项:在您的模型中使用自定义验证器。如果您使用这种技术和 forms.py 中的 ModelForm,那么这应该就是您所需要的。

models.py

from django.core.exceptions import ValidationError

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

    image = models.ImageField(upload_to="/a/b/c/", validators=[validate_image])

【讨论】:

  • 澄清一下,这会在验证之前先完整上传文件,对吗?在这种情况下,我同意 bradley.ayers,您还应该设置网络服务器限制
猜你喜欢
  • 1970-01-01
  • 2014-04-04
  • 1970-01-01
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
相关资源
最近更新 更多