Django和动态生成的图像 [英] Django and dynamically generated images

查看:106
本文介绍了Django和动态生成的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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

  Accept-Ranges:bytes 
连接:keep-alive
内容长度:14966
内容类型:image / jpeg
日期:Wed,18 Aug 2010 15:36:16 GMT
最后修改:Wed,18 Aug 2010 15:36:16 GMT
服务器:nginx / 0.5.33

这是图像不正确的标题不要加载:

 接受范围:字节
连接:keep-alive
Content-Length: 0
内容类型:image / jpeg
日期:Wed,18 Aug 2010 15:37:47 GMT
最后修改:Wed,18 Aug 2010 15:37:46 GMT
服务器:nginx / 0.5.33

注意Content-Lenth等于零。这可能造成了什么?任何有关如何进一步调试这个问题的想法?



编辑:
当视图被调用时,它调用这个draw 模式的方法。这基本上是它做的(我清除了大部分代码):

  def draw(self):
#打开/创建一个文件
如果不是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)

#创建PIL图像
im = Image.new(mode,(width,height))

#做一些绘图
.....

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

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



如果不断点击F5,在右边的e将最终呈现。

解决方案

在将HTML页面写入磁盘时,我们遇到了这个问题。我们的解决方案是写入一个临时文件,然后原子地重命名该文件。您也可以考虑使用 fsync



完整的来源可以在这里获得: staticgenerator / __ init__.py ,但这里有用的位:

  import os 
import stat
import tempfile

...

f,tmpname = tempfile.mkstemp(dir = directory)
os.write(f,content)
# //docs.python.org/library/os.html#os.fsync
f.flush()
os.fsync(f.fileno())
os.close(f)
#确保它是webserver可读的
os.chmod(tmpname,stat.S_IREAD | stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
#重命名是POSIX
中的原子操作#请参阅:http://docs.python.org/library/os.html#os.rename
os.rename(tmpname,fn)


I have a view in my Django application that automatically creates an image using the PIL, stores it in the Nginx media server, and returns a html template with a img tag pointing to it's url.

This works fine, but I notice an issue. For every 5 times I access this view, in 1 of them the image doesn't render.

I did some investigation and I found something interesting, this is the HTTP response header when the image renders properly:

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

and this is the header when the image doesn't load:

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

Notice the Content-Lenth equals to zero. What could have caused this? Any ideas on how could I further debug this problem?

Edit: When the view is called, it calls this "draw" method of the model. This is basically what it does (I removed the bulk of the code for clarity):

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: This is website: http://xxxcnn7979.hospedagemdesites.ws:8000/cartao/99/

if you keep hitting F5 the image on the right will eventually render.

解决方案

We had this problem a while back when writing HTML pages out to disk. The solution for us was to write to a temporary file and then atomically rename the file. You might also want to consider using fsync.

The full source is available here: staticgenerator/__init__.py, but here are the useful bits:

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)

这篇关于Django和动态生成的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆