Обслуживание динамично сгенерированного ZIP архивирует в Django

Если у вас есть xmllint, вы можете создать подпроцесс и использовать его. xmllint --format <file> довольно-печатает свой входной XML в стандартный вывод.

Обратите внимание, что этот метод использует программу, внешнюю по отношению к python, что делает ее видом хака.

def pretty_print_xml(xml):
    proc = subprocess.Popen(
        ['xmllint', '--format', '/dev/stdin'],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
    )
    (output, error_output) = proc.communicate(xml);
    return output

print(pretty_print_xml(data))
56
задан zuber 15 September 2008 в 22:00
поделиться

5 ответов

Решение следующие.

Использование модуль Python zipfile для создания архива zip, но как файл определяют объект StringIO (конструктор ZipFile требует подобного файлу объекта). Добавьте файлы, которые Вы хотите сжать. Тогда в Вашем Django приложение возвращают содержание объекта StringIO в HttpResponse с набором mimetype к application/x-zip-compressed (или [по крайней мере 112]). Если Вы хотите, можно установить content-disposition заголовок, но это не должно действительно требоваться.

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

43
ответ дан Engineero 7 November 2019 в 16:33
поделиться

Django непосредственно не обрабатывает поколение динамического контента (конкретно zip-файлы). Та работа была бы сделана стандартной библиотекой Python. Можно смотреть на то, как динамично создать zip-файл в Python здесь .

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

В целом, архивируя файлы может быть интенсивный ЦП, но Django не должен быть немного медленнее, чем другая веб-платформа Python.

6
ответ дан ductionist 7 November 2019 в 16:33
поделиться

Я предлагаю использовать отдельную модель для хранения тех временных zip-файлов. Можно создать zip на мухе, сохранить, чтобы смоделировать с filefield и наконец отправить URL пользователю.

Преимущества:

  • Служащие статические zip-файлы с django механизмом медиа (как обычные загрузки).
  • Способность к очистке лишает zip-файлы новизны регулярным выполнением сценария крона (который может использовать поле даты из модели zip-файла).
1
ответ дан carefulweb 7 November 2019 в 16:33
поделиться

Вы не можете только записать ссылку на "сервер zip" или этажерку? То, почему zip архивирует себя, должно быть подано от Django? Сценарий CGI эры 90-х, чтобы генерировать zip и плюнуть ею к stdout является действительно всем, что это требуется здесь, по крайней мере, насколько я вижу.

0
ответ дан Andy Ross 7 November 2019 в 16:33
поделиться

Много вкладов уже было сделано к теме, но так как я столкнулся с этим потоком, когда я сначала исследовал эту проблему, я думал, что добавлю свои собственные два цента.

Интеграция Вашего собственного создания zip, вероятно, не так устойчива и оптимизирована как решения уровня веб-сервера. В то же время мы используем Nginx, и он не идет с модулем из поля.

можно, однако, скомпилировать Nginx с mod_zip модулем (см. здесь для изображения докера с последней стабильной версией Nginx и альпийской базы, делающей его меньший, чем изображение Nginx по умолчанию). Это добавляет потоковые возможности zip.

Затем Django просто должен вручить список файлов для архивирования, все сделанные! Это является немного более допускающим повторное использование для пользований библиотекой для этого ответа списка файлов и предложениями django-zip-stream просто это.

Печально это никогда действительно работало на меня, таким образом, я запустил ветвление с мерами и улучшениями.

можно использовать его в нескольких строках:

def download_view(request, name=""):
    from django_zip_stream.responses import FolderZipResponse
    path = settings.STATIC_ROOT
    path = os.path.join(path, name)

    return FolderZipResponse(path)

Вам нужен способ сделать, чтобы Nginx обслуживал все файлы, которые Вы хотите заархивировать, но вот именно.

0
ответ дан 24 November 2019 в 19:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: