Pergunta

Eu estou escrevendo um banco de imagens com Django, e eu quero adicionar um botão para obter uma versão hi-res de uma imagem (os de baixa resolução é mostrada na página de detalhes). Se eu colocar apenas uma ligação <a>, o navegador abrirá a imagem em vez de baixá-lo. Adicionando um cabeçalho HTTP como:

Content-Disposition: attachment; filename="beach008.jpg"

obras, mas já que é um arquivo estático, eu não quero lidar com o pedido com Django. Atualmente, estou usando NGINX para servir arquivos estáticos, e páginas dinâmicas são redirecionadas via FastCGI para o processo de Django. Estou pensando em usar comando add-header NGINX, mas pode definir a parte filename="xx" ?. Ou talvez haja alguma maneira de lidar com o pedido no Django, mas certifique NGINX servir o conteúdo?

Foi útil?

Solução

Se seu aplicativo Django é aproximada pela nginx você pode usar x-Accell redirecionamento . Você precisa passar um cabeçalho especial em sua resposta, nginx vai intercepet isso e começar a servir o arquivo, você também pode passar Content-Disposition na mesma resposta para forçar um download.

Essa solução é boa se você quiser controlar quais usuários acesso destes arquivos.

Você também pode usar uma configuração 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;
        }

        #match images
        if ($filename ~* ^.*?\.((jpg)|(png)|(gif))$) {
            add_header Content-Disposition "attachment; filename=$filename";
        }
    }

    location /static {
        root /project_root;
    }

Isto irá forçar download em todas as imagens em alguns high_res pasta (mediaroot / high_rest). E para os outros arquivos estáticos ele vai se comportar como normal. Por favor note que este é um corte rápido modificada que funciona para mim. Ele pode ter implicações de segurança, para usá-lo com precaução.

Outras dicas

Eu escrevi um decorador simples, de vista django.views.static.serve

O que funciona para mim perfeitamente.

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

Além disso, você pode jogar com mime-types nginx

http://wiki.codemongers.com/NginxHttpCoreModule#types

Esta solução não funcionou para mim, porque eu queria ter tanto link direto para o arquivo (assim que o usuário pode visualizar imagens, por exemplo), e link para download.

O que eu estou fazendo agora é usar um URL diferente para download do que para 'vistas', e adicionar o nome do arquivo como um arg URL:

meios habituais link: http://xx.com/media/images/lores/f_123123.jpg Download link: http://xx.com/downs/hires/f_12323?beach008.jpg

e nginx tem uma configuração como esta:

    location /downs/ {
        root   /var/www/nginx-attachment;
        add_header Content-Disposition 'attachment; filename="$args"';
    }

mas eu realmente não gosto do cheiro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top