HOWTO · Django

Subir y descargar archivos en Django

Cree un ejemplo en Django en el que un administrador sube un archivo y los visitantes lo descargan como adjunto.

En esta página

Para permitir que un administrador suba un archivo y ofrecer a los visitantes un enlace de descarga, almacene las subidas con el FileField de Django y devuelva el archivo seleccionado con FileResponse. Este tutorial está orientado a Django 5.2 y utiliza el almacenamiento multimedia local para el desarrollo; la integración de Django que se muestra aquí no se ha ejecutado en el entorno de ejecución proporcionado.

Subir y descargar un archivo en Django

Cree un proyecto y una aplicación con django-admin startproject django_project y, desde el directorio que contiene manage.py, ejecute python manage.py startapp blog. Añada "blog.apps.BlogConfig" a INSTALLED_APPS del proyecto en django_project/settings.py.

Los medios subidos están separados de los recursos estáticos, como CSS y JavaScript. Establezca MEDIA_URL = "/media/" y MEDIA_ROOT = BASE_DIR / "media" en settings.py. MEDIA_ROOT es la ubicación en el sistema de archivos para los archivos subidos; MEDIA_URL es el prefijo de URL utilizado para servirlos. Mantenga las subidas fuera del directorio de archivos estáticos.

En blog/models.py, defina un modelo UploadedFile con title = models.CharField(max_length=200) y file = models.FileField(upload_to="uploads/"). Añada def __str__(self): return self.title para que el elemento sea identificable en el panel de administración. Regístrelo en blog/admin.py con admin.site.register(UploadedFile). Después de crear el modelo, ejecute python manage.py makemigrations y python manage.py migrate, y luego cree un administrador con python manage.py createsuperuser.

Añada dos vistas en blog/views.py. La vista principal puede renderizar un queryset como valor de contexto files: return render(request, "blog/home.html", {"files": UploadedFile.objects.all()}). Para la vista de descarga, busque la fila con item = get_object_or_404(UploadedFile, pk=file_id) y devuelva FileResponse(item.file.open("rb"), as_attachment=True, filename=item.file.name.rsplit("/", 1)[-1]). Importe FileResponse, get_object_or_404 y UploadedFile. Esta integración específica de Django no se ha ejecutado aquí. FileResponse transmite el archivo, mientras que as_attachment=True pide al navegador que lo descargue. El archivo almacenado aún debe estar presente en el almacenamiento configurado.

La vista utiliza el componente final de la ruta como nombre que se ofrece al navegador. Este pequeño ejemplo de Python muestra ese paso del nombre de archivo con una ruta de subida almacenada:

Ejecute este ejemplo:

stored_name = "uploads/sample.mp3"
download_name = stored_name.rsplit("/", 1)[-1]
print(download_name)
sample.mp3

En blog/urls.py, asigne la ruta principal a la vista principal y "download/<int:file_id>/" a download_file, dando a esta última el nombre "download_file". Incluya blog.urls desde la configuración de URL del proyecto con path("", include("blog.urls")). En blog/templates/blog/home.html, renderice un enlace para cada elemento:

{% for item in files %}
  <h2>{{ item.title }}</h2>
  <a href="{% url 'download_file' item.pk %}">Download {{ item.title }}</a>
{% endfor %}

Ejecute el servidor de desarrollo con python manage.py runserver, inicie sesión en /admin/ y añada un UploadedFile con un título y un pequeño archivo de ejemplo. La página principal debería mostrar su título; al seleccionar su enlace, debería devolver ese archivo como adjunto de descarga. Este tutorial describe el comportamiento esperado, pero no incluye ninguna salida de ejecución observada.

En un sitio de desarrollo local, Django puede servir los medios subidos añadiendo static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) a los patrones de URL del proyecto cuando settings.DEBUG es verdadero; importe static desde django.conf.urls.static. Esta función auxiliar es para el desarrollo y no es un servidor de archivos de producción. En producción, configure el servidor web o el almacenamiento de objetos para servir los medios, y decida si cada archivo es público o requiere autorización. Si las subidas son privadas, proteja la vista de descarga con una comprobación de permisos adecuada en lugar de exponer MEDIA_URL directamente. Valide las subidas y aplique límites de tamaño y de tipo de archivo que se ajusten a la aplicación.