Esta semana me ha tocado crear la posibilidad de descargar archivos desde el servidor para un usuario con permisos específicos, luego de revisar bastante rato la web para ver si conseguía un código que ya estuviera hecho, conseguí algunos pero desafortunadamente no me funcionaron, siendo así la situación me puse manos a la obra para construir la vista por mi cuenta.
Primero que nada, se debe importar al inicio del archivo el módulo de python: import mimetypes
Particularmente utilizo estos métodos para verificar el tipo de usuario:
1.- Para verificar que el usuario pertenece a un grupo:
if request.user.groups.filter(name='mentores').exists()
2.- Para verificar si es un super usuario:
if request.user.is_superuser
Luego de verificar que los usarios eran los correctos sigo con estos pasos:
El relative_path que verás en la vista de descarga viene de un método que contiene el campo FileField de los modelos de django.
Este dato viene de una vista general que lista todos los archivos de un usuario; Para generar la vista de descarga utilizo el método "URL":
<td><a href="{% url 'descarga-archivos' archivo.file.name %}">{{ archivo.file.name }}</a></td>
Esto llama a la vista 'descarga-archivos' y pasa la variable archivo.file.name
La vista queda así:
def download_pdf_file(request, relative_path):
if relative_path != '':
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ruta_archivo = '{}/{}'.format(settings.MEDIA_ROOT, relative_path)
path = open(ruta_archivo, 'rb')
mime_type, _ = mimetypes.guess_type(ruta_archivo)
response = HttpResponse(path, content_type=mime_type)
response['Content-Disposition'] = "attachment; filename=%s" % relative_path[0:16]
return response
Primero defino el directorio base del proyecto con:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Defino la ruta del archivo:
ruta_archivo= '{}/{}'.format(settings.MEDIA_ROOT, relative_path)
A continuación abro el archivo: path = open(filepath, 'rb')
Seteo el Mimetype usando la función de python:
mime_type, _ = mimetypes.guess_type(ruta_archivo)
Seteo el contenido del response: response = HttpResponse(path, content_type=mime_type)
Y por último seteo el header del response y corto el nombre del archivo del caracter 0 al 16 "[0:16]":
response['Content-Disposition'] = "attachment; filename=%s" % relative_path[0:16]
Si el caso es que el archivo es una imagen se descargará automáticamente y deberás buscarla en la carperta que tengas configurada para las descargas, si fuera otro tipo de archivo se abrirá una ventana como la siguiente:
Si te ha gustado el artículo o tienes alguna preguta deja tu comentario :-D