Rozwiązanie jest następujące.
Użyj modułu Python zipfile do utworzenia archiwum zip, ale jako plik określ obiekt StringIO (konstruktor ZipFile wymaga obiektu podobnego do pliku). Dodaj pliki, które chcesz skompresować. Następnie w aplikacji Django zwróć zawartość obiektu StringIO w HttpResponse
z zestawem MIME ustawionym na application/x-zip-compressed
(lub co najmniej application/octet-stream
). Jeśli chcesz, możesz ustawić nagłówek content-disposition
, ale nie powinno to być naprawdę wymagane.
Ale uwaga, tworzenie archiwów zip na każde żądanie jest zły pomysł, a to może zabić serwer (nie licząc timeoutów jeśli archiwa są duże). Podejście pod kątem wydajności polega na buforowaniu wygenerowanego wyjścia w systemie plików i generowaniu go tylko po zmianie plików źródłowych. Jeszcze lepszym pomysłem jest przygotowanie archiwów z wyprzedzeniem (np. Przez pracę cron) i serwer sieciowy obsługujący je w zwykły sposób.
StringIO nie będzie dostępny w Pythonie 3.0, więc możesz chcieć odpowiednio dopasować swój kod. –
Nie zniknął, po prostu przeniesiony do modułu io. http://docs.python.org/3.0/library/io.html#io.StringIO –
Podobnie jak w przypadku ręcznego tworzenia HttpResponse, nie można użyć tego jako bufora? Mam na myśli przekazanie odpowiedzi do 'zipfile' i pozwolenie jej na bezpośrednie zapisanie. Zrobiłem to z innymi rzeczami. Jeśli masz do czynienia z potężnymi strumieniami, może to być szybsze i bardziej wydajne. – Oli