Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

310
Vistas
Agregar disposición de contenido dinámico para nombres de archivo (amazon S3) en python

Tengo un modelo de Django que guarda el nombre del archivo como "uuid4().pdf". Donde uuid4 genera un uuid aleatorio para cada instancia creada. Este nombre de archivo también se almacena en el servidor Amazon S3 con el mismo nombre.

Estoy tratando de agregar una disposición personalizada para el nombre de archivo que subo a Amazon s3, esto se debe a que quiero ver un nombre personalizado cada vez que descargo el archivo, no el uuid. Al mismo tiempo, quiero que los archivos se almacenen en s3 con el nombre de archivo uuid.

Entonces, estoy usando django-storages con python 2.7. He intentado agregar content_disposition en configuraciones como esta:

 AWS_CONTENT_DISPOSITION = 'core.utils.s3.get_file_name'

donde get_file_name() devuelve el nombre del archivo.

También he intentado agregar esto a la configuración:

 AWS_HEADERS = { 'Content-Disposition': 'attachments; filename="%s"'% get_file_name(), }

¡sin suerte!

¿Alguien de ustedes sabe implementar esto?

about 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

La versión actual de S3Boto3Storage de django-storages admite la variable de configuración global AWS_S3_OBJECT_PARAMETERS , que también permite modificar ContentDisposition . Pero el problema es que se aplica tal cual a todos los objetos que se suben al s3 y, además, afecta a todos los modelos que trabajan con el almacenamiento, lo que puede llegar a no ser el resultado esperado.

El siguiente truco funcionó para mí.

 from storages.backends.s3boto3 import S3Boto3Storage class DownloadableS3Boto3Storage(S3Boto3Storage): def _save_content(self, obj, content, parameters): """ The method is called by the storage for every file being uploaded to S3. Below we take care of setting proper ContentDisposition header for the file. """ filename = obj.key.split('/')[-1] parameters.update({'ContentDisposition': f'attachment; filename="{filename}"'}) return super()._save_content(obj, content, parameters)

Aquí anulamos el método de guardado nativo del objeto de almacenamiento y nos aseguramos de que se establezca la disposición de contenido adecuada en cada archivo. Por supuesto, debe alimentar este almacenamiento al campo en el que está trabajando:

 my_file_filed = models.FileField(upload_to='mypath', storage=DownloadableS3Boto3Storage())
about 4 years ago · Santiago Trujillo Denunciar

0

En caso de que alguien encuentre esto, como lo hice yo: ninguna de las soluciones mencionadas en SO me funcionó en Django 3.0.

Docstring de S3Boto3Storage sugiere anular S3Boto3Storage.get_object_parameters ; sin embargo, este método solo recibe el name del archivo cargado, que en este punto ha sido modificado por upload_to y puede diferir del original.

Lo que funcionó es lo siguiente:

 class S3Boto3CustomStorage(S3Boto3Storage): """Override some upload parameters, such as ContentDisposition header.""" def _get_write_parameters(self, name, content): """Set ContentDisposition header using original file name. While docstring recomments overriding `get_object_parameters` for this purpose, `get_object_parameters` only gets a `name` which is not the original file name, but the result of `upload_to`. """ params = super()._get_write_parameters(name, content) original_name = getattr(content, 'name', None) if original_name and name != original_name: content_disposition = f'attachment; filename="{original_name}"' params['ContentDisposition'] = content_disposition return params

y luego usar este almacenamiento en el campo de archivo, por ejemplo:

 file_field = models.FileField( upload_to=some_func, storage=S3Boto3CustomStorage(), )

Independientemente de la solución que se le ocurra, no cambie file_field.storage.object_parameters directamente (por ejemplo, en save() del modelo como se sugirió en una pregunta similar), porque esto cambiará el encabezado ContentDisposition para cargas de archivos posteriores de cualquier campo que use el mismo almacenamiento. Que no es lo que probablemente quieras.

about 4 years ago · Santiago Trujillo Denunciar

0

Supongo que está utilizando S3BotoStorage de django-storages , así que mientras carga el archivo en S3, anule el método save() del modelo y establezca el encabezado allí.

Estoy dando un ejemplo a continuación:

 class ModelName(models.Model): sthree = S3BotoStorage() def file_name(self,filename): ext = filename.split('.')[-1] name = "%s/%s.%s" % ("downloads", uuid.uuid4(), ext) return name upload_file = models.FileField(upload_to=file_name,storage = sthree) def save(self): self.upload_file.storage.headers = {'Content-Disposition': 'attachments; filename="%s"' %self.upload_file.name} super(ModelName, self).save()
about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda