En mi caso, tengo el servidor Django 1.11 actuando como proxy. Cuando hace clic en "descargar" desde el navegador, envía una solicitud al proxy django que descarga archivos de otro servidor y los procesa, después de lo cual debe "enviarlos" al navegador para permitir que el usuario los descargue. Mi proxy descarga y procesa los archivos fragmento por fragmento. ¿Cómo puedo enviar fragmentos al navegador cuando estén listos para que el usuario finalmente descargue un solo archivo?
En la práctica, debo permitirle descargar un archivo que aún no está listo, como una secuencia.
def my_download(self, res) # some code file_handle = open(local_path, 'wb', self.chunk_size) for chunk in res.iter_content(self.chunk_size): i = i+1 print("index: ", i, "/", chunks) if i > chunks-1: is_last = True # some code on the chunk # Here, instead of saving the chunk locally, I would like to allow it to download it directly. file_handle.write(chunk) file_handle.close() return TrueGracias de antemano, saludos.
Esta pregunta debe marcarse como duplicada de esta publicación: Sirviendo archivos grandes (con cargas altas) en Django
Siempre trate de encontrar la respuesta antes de crear una pregunta en SO, ¡por favor!
Esencialmente, la respuesta está incluida en la Documentación de Django: ejemplo de "Transmisión de archivos CSV grandes" y aplicaremos la pregunta anterior en ese ejemplo:
Puede usar StreamingHttpResponse de Django y wsgiref.util.FileWrapper de Python para servir un archivo grande en fragmentos de manera efectiva y sin cargarlo en la memoria.
def my_download(request): file_path = 'path/to/file' chunk_size = DEFINE_A_CHUNK_SIZE_AS_INTEGER filename = os.path.basename(file_path) response = StreamingHttpResponse( FileWrapper(open(file_path, 'rb'), chunk_size), content_type="application/octet-stream" ) response['Content-Length'] = os.path.getsize(file_path) response['Content-Disposition'] = "attachment; filename=%s" % filename return response Ahora, si desea aplicar algún procesamiento al archivo fragmento por fragmento, puede utilizar el iterador generado por FileWrapper :
Coloque su código de procesamiento de fragmentos en una función que DEBE devolver el fragmento:
def chunk_processing(chunk): # Process your chunk here # Be careful to preserve chunk's initial size. return processed_chunk Ahora aplique la función dentro de StreamingHttpResponse :
response = StreamingHttpResponse( ( process_chunk(chunk) for chunk in FileWrapper(open(file_path, 'rb'), chunk_size ),content_type="application/octet-stream" )