cabeçalhos HTTP personalizados para arquivos estáticos com Django

votos
9

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

Content-Disposition: attachment; filename=beach008.jpg

funciona, 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 NGINX add-headercomando, mas pode definir a filename=xxparte ?. Ou talvez haja alguma maneira de lidar com o pedido no Django, mas fazer NGINX servir o conteúdo?

Publicado 04/11/2008 em 20:36
fonte usuário
Em outras línguas...                            


3 respostas

votos
10

Se seu aplicativo Django é aproximada pela nginx você pode usar x-Accell-redirect . 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 alguma pasta high_res (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.

Respondeu 22/12/2008 em 16:06
fonte usuário

votos
4

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

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 nginx mime-types

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.

Respondeu 04/11/2008 em 22:40
fonte usuário

votos
0

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:

habitual link de mídia: 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 dele.

Respondeu 04/11/2008 em 23:09
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more