Подтвердить что ты не робот

Лучший способ написать образ Django HttpResponse()

Мне нужно безопасно обслуживать изображения только для проверенных пользователей (т.е. они не могут служить статическими файлами). В настоящее время у меня есть следующий вид Python в моем проекте Django, но он кажется неэффективным. Любые идеи для лучшего способа?

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

(Изображение импортируется из PIL.)

4b9b3361

Ответ 1

Ну, иногда требуется повторное кодирование (например, использование водяного знака над изображением при сохранении оригинального нетронутого), но для самых простых случаев вы можете использовать:

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

Ответ 2

Просто наткнулся на несколько плохой совет (для производства) и подумал, что я бы упомянул X-Sendfile, который работает как с Apache, так и с Nginx и, возможно, с другими веб-серверами.

https://pythonhosted.org/xsendfile/

Современные веб-серверы, такие как Nginx, обычно способны обслуживать файлы быстрее, эффективнее и надежнее, чем любое размещаемое веб-приложение. Эти серверы также могут отправлять клиенту файл на диске, как указано в веб-приложениях, которые они размещают. Эта функция широко известна как X-Sendfile.

Эта простая библиотека позволяет любому приложению WSGI использовать X-Sendfile, чтобы они могли контролировать, может ли файл обслуживаться или что делать, когда файл обслуживается, без написания специфичных для сервера расширений. Варианты использования включают в себя:

  • Ограничьте загрузку документов для аутентифицированных пользователей.

  • Журнал кто скачал файл. Принудительно загрузить файл вместо отображается браузером или обслуживается с именем, отличным от один на диске, установив заголовок Content-Disposition.

Основная идея заключается в том, что вы открываете файл и передаете этот дескриптор веб-серверу, который затем возвращает байты клиенту, освобождая ваш код Python для обработки следующего запроса. Это намного эффективнее, чем решение, описанное выше, поскольку медленный клиент на другом конце может повесить поток Python на столько времени, сколько потребуется для загрузки файла.

Вот репозиторий, который показывает, как это сделать для различных веб-серверов, и хотя он довольно старый, он по крайней мере даст вам представление о том, что вам нужно делать. https://github.com/johnsensible/django-sendfile