mostrar - manejo de imagenes django
encabezados HTTP personalizados para archivos estáticos con Django (3)
Escribí un decorador simple para la vista django.views.static.serve
Lo cual funciona a mi perfección.
def serve_download(view_func):
def _wrapped_view_func(request, *args, **kwargs):
response = view_func(request, *args, **kwargs)
response[''Content-Type''] = ''application/octet-stream'';
import os.path
response[''Content-Disposition''] = ''attachment; filename="%s"'' % os.path.basename(kwargs[''path''])
return response
return _wrapped_view_func
También puedes jugar con nginx mime-types
http://wiki.codemongers.com/NginxHttpCoreModule#types
Esta solución no funcionó para mí, porque quería tener un enlace directo para el archivo (para que el usuario pueda ver imágenes, por ejemplo) y un enlace de descarga.
Estoy escribiendo un banco de imágenes con Django, y quiero agregar un botón para obtener una versión de alta resolución de una imagen (la baja resolución se muestra en la página de detalles). Si pongo solo un enlace <a>
, el navegador abrirá la imagen en lugar de descargarla. Agregar un encabezado HTTP como:
Content-Disposition: attachment; filename="beach008.jpg"
funciona, pero como es un archivo estático, no quiero manejar la solicitud con Django. Actualmente, estoy usando NGINX para servir archivos estáticos, y las páginas dinámicas se redirigen a través de FastCGI al proceso de Django. Estoy pensando en utilizar el comando NGINX add-header
, pero ¿podría establecer el filename="xx"
del filename="xx"
? ¿O tal vez hay alguna forma de manejar la solicitud en Django, pero hacer que NGINX sirva el contenido?
Si su aplicación django está proxys por nginx, puede usar x-accell-redirect . Debe pasar un encabezado especial en su respuesta, nginx lo interceptará y comenzará a servir el archivo, también puede pasar Content-Disposition en la misma respuesta para forzar una descarga.
Esa solución es buena si desea controlar qué usuarios acceden a estos archivos.
También puedes usar una configuración como esta:
#files which need to be forced downloads
location /static/high_res/ {
root /project_root;
#don''t ever send $request_filename in your response, it will expose your dir struct, use a quick regex hack to find just the filename
if ($request_filename ~* ^.*?/([^/]*?)$)
{
set $filename $1;
}
if ($filename ~* ^.*?/.(jpg)|(png)|(gif)$){
add_header Content-Disposition "attachment; filename=$filename";
}
}
location /static {
root /project_root;
}
Esto forzará la descarga en todas las imágenes en alguna carpeta high_res (MEDIAROOT / high_rest). Y para los demás archivos estáticos, se comportará de forma normal. Tenga en cuenta que este es un truco rápido modificado que funciona para mí. Puede tener implicaciones de seguridad, así que úselo con precaución.
Lo que estoy haciendo ahora es utilizar una URL diferente para descargar que para ''vistas'', y agregar el nombre de archivo como una URL arg:
enlace de medios habitual: http://xx.com/media/images/lores/f_123123.jpg
enlace de descarga: http://xx.com/downs/hires/f_12323?beach008.jpg
y nginx tiene una configuración como esta:
location /downs/ {
root /var/www/nginx-attachment;
add_header Content-Disposition ''attachment; filename="$args"'';
}
pero realmente no me gusta el olor de eso.