将图像写入Django HttpResponse()的最佳方法

时间:2010-06-09 04:50:33

标签: image django-views

我需要安全地向经过验证的用户提供图像(即它们不能作为静态文件提供)。我目前在我的Django项目中有以下Python视图,但它似乎效率低下。想要更好的方法吗?

def secureImage(request,imagePath):
    response = HttpResponse(mimetype="image/png")
    img = Image.open(imagePath)
    img.save(response,'png')
    return response

(图像从PIL导入。)

3 个答案:

答案 0 :(得分:73)

嗯,有时需要重新编码(即在保持原始图像不变的情况下在图像上应用水印),但对于最简单的情况,您可以使用:

try:
    with open(valid_image, "rb") as f:
        return HttpResponse(f.read(), content_type="image/jpeg")
except IOError:
    red = Image.new('RGBA', (1, 1), (255,0,0,0))
    response = HttpResponse(content_type="image/jpeg")
    red.save(response, "JPEG")
    return response

答案 1 :(得分:1)

只是偶然发现了一些不好的建议(用于生产),并认为我会提到X-Sendfile,它可以与Apache和Nginx以及其他Web服务器一起使用。

https://pythonhosted.org/xsendfile/

  

像Nginx这样的现代Web服务器通常能够比它们所托管的任何Web应用程序更快,更高效,更可靠地提供文件。这些服务器还能够将它们托管的Web应用程序指定的磁盘上的文件发送到客户端。此功能通常称为X-Sendfile。

     

这个简单的库使任何WSGI应用程序都可以轻松使用X-Sendfile,这样它们就可以控制是否可以提供文件或提供文件时执行其他操作,而无需编写服务器特定的扩展名。用例包括:

     
      
  • 将文档下载限制为经过身份验证的用户。

  •   
  • 记录谁下载了文件。强制下载文件而不是   由浏览器呈现,或以不同于   通过设置Content-Disposition标头将其放在磁盘上。

  •   

基本思想是打开文件并将该句柄传递回Web服务器,然后Web服务器将字节返回给客户端,从而释放Python代码以处理下一个请求。这比上面的解决方案性能要好得多,因为另一端速度较慢的客户端可能会在您下载文件时挂起python线程。

这里是一个回购,它显示了如何针对各种Web服务器执行此操作,尽管它已经很老了,但它至少会让您对需要执行的操作有所了解。 https://github.com/johnsensible/django-sendfile

答案 2 :(得分:1)

利用FileResponse
一种更简洁的方式,这里我们不必担心 Content-LengthContent-Type 标头,当它们可以从 open() 的内容中猜出时自动设置。

from django.http import FileResponse

def send_file(response):

    img = open('media/hello.jpg', 'rb')

    response = FileResponse(img)

    return response
相关问题