【问题标题】:Django and dynamically generated imagesDjango 和动态生成的图像
【发布时间】:2011-03-31 16:25:10
【问题描述】:

我的 Django 应用程序中有一个视图,它使用 PIL 自动创建一个图像,将其存储在 Nginx 媒体服务器中,并返回一个带有指向其 url 的 img 标签的 html 模板。

这工作正常,但我注意到一个问题。每 5 次访问此视图,其中 1 次图像未呈现。

我做了一些调查,发现了一些有趣的东西,这是图像正确呈现时的 HTTP 响应标头:

Accept-Ranges:bytes
Connection:keep-alive
Content-Length:14966
Content-Type:image/jpeg
Date:Wed, 18 Aug 2010 15:36:16 GMT
Last-Modified:Wed, 18 Aug 2010 15:36:16 GMT
Server:nginx/0.5.33

这是图片未加载时的标题:

Accept-Ranges:bytes
Connection:keep-alive
Content-Length:0
Content-Type:image/jpeg
Date:Wed, 18 Aug 2010 15:37:47 GMT
Last-Modified:Wed, 18 Aug 2010 15:37:46 GMT
Server:nginx/0.5.33

注意 Content-Lenth 等于 0。是什么原因造成的?关于如何进一步调试此问题的任何想法?

编辑: 当视图被调用时,它会调用模型的这个“绘制”方法。这基本上就是它的作用(为了清楚起见,我删除了大部分代码):

def draw(self):
    # Open/Creates a file
    if not self.image:
        (fd, self.image) = tempfile.mkstemp(dir=settings.IMAGE_PATH, suffix=".jpeg")
        fd2 = os.fdopen(fd, "wb")
    else:
        fd2 = open(os.path.join(settings.SITE_ROOT, self.image), "wb")

    # Creates a PIL Image
    im = Image.new(mode, (width, height))

    # Do some drawing
    .....

    # Saves
    im = im.resize((self.get_size_site(self.width),
                    self.get_size_site(self.height)))
    im.save(fd2, "JPEG")
    fd2.close()

Edit2:这是网站: http://xxxcnn7979.hospedagemdesites.ws:8000/cartao/99/

如果你一直按 F5,右侧的图像最终会呈现出来。

【问题讨论】:

  • 当content-length为零时,能否判断图片是否生成成功并存在于服务器上?
  • 是的,它是正确生成的,当您尝试直接访问图片网址时,它会打开。
  • 为什么要附加并改变 get 查询字符串?
  • 你真的应该尝试 django-imagekit 而不是自己滚动这些东西。如果您有好的代码要添加到其中,那么对所有相关人员都会更好。
  • 感谢您的提示!我不知道 imagekit

标签: python django http-headers nginx python-imaging-library


【解决方案1】:

不久前我们在将 HTML 页面写入磁盘时遇到了这个问题。我们的解决方案是写入一个临时文件,然后自动重命名该文件。您可能还想考虑使用fsync

完整的源代码在这里:staticgenerator/__init__.py,但这里是有用的位:

import os
import stat
import tempfile

...

f, tmpname = tempfile.mkstemp(dir=directory)
os.write(f, content)
# See http://docs.python.org/library/os.html#os.fsync
f.flush()
os.fsync(f.fileno())
os.close(f)
# Ensure it is webserver readable
os.chmod(tmpname, stat.S_IREAD | stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
# Rename is an atomic operation in POSIX
# See: http://docs.python.org/library/os.html#os.rename
os.rename(tmpname, fn)

【讨论】:

    猜你喜欢
    • 2010-11-07
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 2011-01-03
    • 2011-11-24
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多