Джанго и динамически генерируемые изображения - PullRequest
5 голосов
/ 18 августа 2010

В моем приложении 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

и это заголовок, когда изображение не загружается:

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 равен нулю.Что могло вызвать это?Любые идеи о том, как я мог бы далее отладить эту проблему?

Редактировать: Когда вызывается представление, оно вызывает этот метод "рисования" модели.Это в основном то, что он делает (я убрал большую часть кода для ясности):

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, изображение справа в конечном итоге будет визуализироваться.

1 Ответ

4 голосов
/ 26 августа 2010

У нас была эта проблема некоторое время назад при записи 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)
...