python - files - open file django
Django: crea un zip de varios archivos y hazlo descargable (2)
Entonces, como entiendo, su problema no es cómo generar dinámicamente este archivo, sino crear un enlace para que la gente lo descargue ...
Lo que sugiero es lo siguiente:
0) Cree un modelo para su archivo, si desea generarlo dinámicamente, no use FileField, sino la información que necesita para generar este archivo:
class ZipStored(models.Model):
zip = FileField(upload_to="/choose/a/path/")
1) Crea y almacena tu Zip. Este paso es importante, creas tu zip en la memoria y luego lo conviertes para asignarlo al FileField:
function create_my_zip(request, [...]):
[...]
# This is a in-memory file
file_like = StringIO.StringIO()
# Create your zip, do all your stuff
zf = zipfile.ZipFile(file_like, mode=''w'')
[...]
# Your zip is saved in this "file"
zf.close()
file_like.seek(0)
# To store it we can use a InMemoryUploadedFile
inMemory = InMemoryUploadedFile(file_like, None, "my_zip_%s" % filename, ''application/zip'', file_like.len, None)
zip = ZipStored(zip=inMemory)
# Your zip will be stored!
zip.save()
# Notify the user the zip was created or whatever
[...]
2) Crear una url, por ejemplo, obtener un número que coincida con el ID, también puede utilizar un campo de slug ( this )
url(r''^get_my_zip/(/d+)$'', "zippyApp.views.get_zip")
3) Ahora la vista, esta vista devolverá el archivo que coincida con la ID pasada en la url, también puede usar un slug para enviar el texto en lugar de la ID, y hacer que el slugfield filtre para obtener.
function get_zip(request, id):
myzip = ZipStored.object.get(pk = id)
filename = myzip.zip.name.split(''/'')[-1]
# You got the zip! Now, return it!
response = HttpResponse(myzip.file, content_type=''application/zip'')
response[''Content-Disposition''] = ''attachment; filename=%s'' % filename
Posible duplicado:
Al servicio de archivos ZIP generados dinámicamente en Django
(No dude en señalarme cualquier posible duplicado si los he perdido)
He visto este fragmento: http://djangosnippets.org/snippets/365/
y esta answer:
pero me pregunto cómo puedo modificarlos para que se ajusten a mis necesidades: quiero que se compriman múltiples archivos y que el archivo esté disponible como descarga a través de un enlace (o generado dinámicamente a través de una vista). Soy nuevo en Python y Django, así que no sé cómo hacerlo.
¡Gracias de antemano!
He publicado esto en la pregunta duplicada a la que Willy enlazó, pero como las preguntas con una recompensa no pueden cerrarse como duplicado, también podría copiarla aquí:
import os
import zipfile
import StringIO
from django.http import HttpResponse
def getfiles(request):
# Files (local path) to put in the .zip
# FIXME: Change this (get paths from DB etc)
filenames = ["/tmp/file1.txt", "/tmp/file2.txt"]
# Folder name in ZIP archive which contains the above files
# E.g [thearchive.zip]/somefiles/file2.txt
# FIXME: Set this to something better
zip_subdir = "somefiles"
zip_filename = "%s.zip" % zip_subdir
# Open StringIO to grab in-memory ZIP contents
s = StringIO.StringIO()
# The zip compressor
zf = zipfile.ZipFile(s, "w")
for fpath in filenames:
# Calculate path for file in zip
fdir, fname = os.path.split(fpath)
zip_path = os.path.join(zip_subdir, fname)
# Add file, at correct path
zf.write(fpath, zip_path)
# Must close zip for all contents to be written
zf.close()
# Grab ZIP file from in-memory, make response with correct MIME-type
resp = HttpResponse(s.getvalue(), mimetype = "application/x-zip-compressed")
# ..and correct content-disposition
resp[''Content-Disposition''] = ''attachment; filename=%s'' % zip_filename
return resp