Django和动态生成的图像

Ces*_*ssa 5 python django nginx http-headers python-imaging-library

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

这很好,但我注意到一个问题.我每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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

注意Content-Lenth等于零.可能是什么导致了这个?关于如何进一步调试此问题的任何想法?

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

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()
Run Code Online (Sandbox Code Playgroud)

编辑2:这是网站:http://xxxcnn7979.hospedagemdesites.ws:8000/cartao / 99/

如果你继续按F5,右边的图像最终会渲染.

Eri*_*ulf 5

不久前我们在将 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)
Run Code Online (Sandbox Code Playgroud)