Entendendo a relação entre o Django e arquivos estáticos

32

Quem está começando com Django eventualmente tropeça em questões envolvendo arquivos estáticos.

Tudo fica mais simples quando você compreende as diferentes relações que o Django estabelece com os assets do seu projeto.

Por padrão, quando você cria um projeto, a app django.contrib.staticfiles já está no INSTALLED_APPS do seu settings.py. É nela que estão implementados os códigos que ajustam o comportamento do framework de acordo com o contexto:

Em desenvolvimento

Quando você inicia o servidor de desenvolvimento do Django com o comando python manage.py runserver e no seu settings.py você tem DEBUG=True, o framework assume que você está em modo de desenvolvimento e serve os assets de cada app, diretamente pelo Django.

Isso é lento, mas em tempo de desenvolvimento não é problema e acaba agilizando muito, pois você não precisa executar o collectstatic à cada asset novo que adiciona ao projeto.

Vale ressaltar que esse comportamento é atrelado ao comando runserver. Se você usar o gunicorn no desenvolvimento, este recurso não estará disponível e você precisará adicionar as linhas abaixo no seu ROOT_URLCONF.

Em produção

Quando no seu settings.py, o DEBUG=False, ele assume que você está em modo produção e não serve nenhum arquivo estático. Nem das apps e nem do STATIC_ROOT que é o destino do comando collectstatic.

Por padrão, o Django espera que você use um servidor web ou uma CDN para servir seus assets, o que é mais seguro e tem melhor performance.

Collectstatic no meio de campo

Para permitir uma fácil transição do modo de desenvolvimento para o modo de produção, usamos o comando collectstatic.

Esse comando encontra os assets do seu projeto e os copia para o STATIC_ROOT definido no seu settings.py.

Depois de copiar todos os arquivos ele ativa um mecanismo de pós-processamento customizável, que pode desde minificar os seus arquivos até enviá-los para a AmazonS3, por exemplo.

Mas existe um “meio termo”?

Como fazer para o Django servir os arquivos copiados para o STATIC_ROOT mesmo em modo produção, ou seja, com DEBUG=False?

Apesar de não ser ideal, essa é uma necessidade relativamente comum, principalmente para quem está prototipando aplicações utilizando o Heroku.

A solução tradicional é adicionar ao ROOT_URLCONF uma rota para uma view builtin do Django:

A solução mais recomendada, é utilizar a app dj-static que faz a mesma coisa de forma mais segura.

Expliquei ou compliquei? Espero que agora você encare os arquivos estáticos com mais tranquilidade. 😉

[]’s, HB!

você pode gostar também
32 comentários
  1. Victor Acioly Diz

    Começando agora. Espero um dia entender conseguir assimilar tudo o que foi dito aqui.
    😉

    1. Henrique Bastos Diz

      Manda ver nas perguntas que a gente vai conversando por aqui. Se você não entendeu tudo, sinal que tem espaço pra gente melhorar o artigo e deixar ele mais claro. 😉

      1. Victor Acioly Diz

        A minha maior dificuldade tem sido encontrar um curso ou livro que me leve do zero ao nível independente (capaz de procurar as coisas sozinho e evoluir de acordo com as minhas necessidades). Sinceramente, não sei nem te perguntar nada direito ainda.
        Acabei de comprar um curso da Udemy e ouvi o professor falar de arquivos estáticos. Rapidamente “Googlei” e encontrei seu artigo que, a propósito, já está salvo nos favoritos para a leitura de um dia quando eu souber o que é assets e outros paranauês mais.
        P.s: Se alguém tiver sugestões de referências para a categoria “Mais Perdidos da Programação WEB” tenha piedade deu. 😉

      2. Henrique Bastos Diz

        Falaê! Massa! Dá uma olhada no http://welcometothedjango.com.br Pode te interessar. 😉

      3. Victor Acioly Diz

        Inscrito.

  2. Silas Vasconcelos Diz

    Sou de bola, parabéns!

  3. Silas Vasconcelos Diz

    Sou de bola, parabéns!

  4. Cezar Cruz Diz

    Bem Explicado, estava com essa duvida jah tinha um tempo, obrigado.

  5. HB Diz

    Testando disqus

  6. Andreas Diz

    Não estou conseguindo acessar os arquivos de media. Alguem pode me ajudar?

    meu settings.py:

    SETTINGS_DIR = os.path.realpath(os.path.dirname(__file__))

    MEDIA_ROOT = os.path.join(SETTINGS_DIR, ‘media’)

    MEDIA_URL = ‘/media/’

  7. Roberto Almeida Diz

    Problema resolvido, faltava fazer esta configuração:
    STATICFILES_DIRS = (
    os.path.join(BASE_DIR, ‘static’),
    )

  8. Roberto Almeida Diz

    Problema resolvido, faltava fazer esta configuração:
    STATICFILES_DIRS = (
    os.path.join(BASE_DIR, ‘static’),
    )

  9. Roberto Almeida Diz

    Problema resolvido, faltava fazer esta configuração:
    STATICFILES_DIRS = (
    os.path.join(BASE_DIR, ‘static’),
    )

  10. Roberto Almeida Diz

    No meu caso nem com o dj-static conseguí exibir as imagens, acredito que o problema esteja na localização da pasta dentro do project ou algo parecido.

    As imagens estão fisicamente na pasta “D:webserverwwwgerenciadorgerenciadorstaticimg”

    Meu arquivo settings.py está assim:
    STATIC_ROOT = ‘staticfiles’
    STATIC_URL = ‘/static/’

    Na minha template instancio as imagens assim:
    {% load staticfiles %}

    1. Henrique Bastos Diz

      O STATIC_ROOT tem que ser o caminho absoluto.

      Se vc adicionou lá no STATICFILES_DIRS, e funcionou, isso aconteceu pq o DEBUG está True.

      Em produção vc vai usar o collectstatic e o DEBUG=False. Com isso vai dar problema devido o valor do seu STATIC_ROOT.

      Faça algo como:

      STATIC_ROOT = os.path.join(BASE_DIR, ‘static’)

      Mas isso vai fazer o local do seus assets colidir com o destino do collectstatic. Então eu sugiro que guarde os assets em um diretório “assets”, fazendo:

      STATICFILES_DIRS = (os.path.join(BASE_DIR, ‘assets’),)

  11. Roberto Almeida Diz

    No meu caso nem com o dj-static conseguí exibir as imagens, acredito que o problema esteja na localização da pasta dentro do project ou algo parecido.

    As imagens estão fisicamente na pasta “D:webserverwwwgerenciadorgerenciadorstaticimg”

    Meu arquivo settings.py está assim:
    STATIC_ROOT = ‘staticfiles’
    STATIC_URL = ‘/static/’

    Na minha template instancio as imagens assim:
    {% load staticfiles %}

    1. Henrique Bastos Diz

      O STATIC_ROOT tem que ser o caminho absoluto.

      Se vc adicionou lá no STATICFILES_DIRS, e funcionou, isso aconteceu pq o DEBUG está True.

      Em produção vc vai usar o collectstatic e o DEBUG=False. Com isso vai dar problema devido o valor do seu STATIC_ROOT.

      Faça algo como:

      STATIC_ROOT = os.path.join(BASE_DIR, ‘static’)

      Mas isso vai fazer o local do seus assets colidir com o destino do collectstatic. Então eu sugiro que guarde os assets em um diretório “assets”, fazendo:

      STATICFILES_DIRS = (os.path.join(BASE_DIR, ‘assets’),)

  12. Fabiano Góes Diz

    show de bola Henrique, ficou muito bem explicado e eu que já vinha usando as convenções de static dentro das apps pude compreender o que ocorre e como o django trabalho por traz das câmeras, ficou tudo mais claro. valeu!!!

  13. Fabiano Góes Diz

    show de bola Henrique, ficou muito bem explicado e eu que já vinha usando as convenções de static dentro das apps pude compreender o que ocorre e como o django trabalho por traz das câmeras, ficou tudo mais claro. valeu!!!

  14. Fabiano Góes Diz

    show de bola Henrique, ficou muito bem explicado e eu que já vinha usando as convenções de static dentro das apps pude compreender o que ocorre e como o django trabalho por traz das câmeras, ficou tudo mais claro. valeu!!!

  15. Jonatas C. D. Diz

    boa, HB

    até porque recentemente tenho visto mais e mais perguntas sobre como lidar com statics – no caso mais voltado ao Django 1.5+

  16. jonatascd Diz

    boa, HB

    até porque recentemente tenho visto mais e mais perguntas sobre como lidar com statics – no caso mais voltado ao Django 1.5+

  17. jonatascd Diz

    boa, HB

    até porque recentemente tenho visto mais e mais perguntas sobre como lidar com statics – no caso mais voltado ao Django 1.5+

  18. Gustavo Carvalho Diz

    Cara, post muito bom, parabéns.
    Tem muita gente que sofre quando está aprendendo Django e precisa lidar com arquivos estáticos, eu mesmo, sofri um bocado até entender como django trata esse tipo de arquivos.

    1. Henrique Bastos Diz

      Valeu @jonatascd:disqus e @disqus_LMvc5nfcLC:disqus! A inspiração veio de uma dúvida do Gilmar Soares nessa última turma do #welcometothedjango.

  19. Gustavo Carvalho Diz

    Cara, post muito bom, parabéns.
    Tem muita gente que sofre quando está aprendendo Django e precisa lidar com arquivos estáticos, eu mesmo, sofri um bocado até entender como django trata esse tipo de arquivos.

    1. Henrique Bastos Diz

      Valeu @jonatascd:disqus e @disqus_LMvc5nfcLC:disqus! A inspiração veio de uma dúvida do Gilmar Soares nessa última turma do #welcometothedjango.

  20. Gustavo Carvalho Diz

    Cara, post muito bom, parabéns.
    Tem muita gente que sofre quando está aprendendo Django e precisa lidar com arquivos estáticos, eu mesmo, sofri um bocado até entender como django trata esse tipo de arquivos.

    1. Henrique Bastos Diz

      Valeu @jonatascd:disqus e @disqus_LMvc5nfcLC:disqus! A inspiração veio de uma dúvida do Gilmar Soares nessa última turma do #welcometothedjango.

      1. Roberto Almeida Diz

        No meu caso nem com o dj-static conseguí exibir as imagens, acredito que o problema esteja na localização da pasta dentro do project ou algo parecido.

        As imagens estão fisicamente na pasta “D:webserverwwwgerenciadorgerenciadorstaticimg”

        Meu arquivo settings.py está assim:
        STATIC_ROOT = ‘staticfiles’
        STATIC_URL = ‘/static/’

        Na minha template instancio as imagens assim:
        {% load staticfiles %}

      2. Henrique Bastos Diz

        O STATIC_ROOT tem que ser o caminho absoluto.

        Se vc adicionou lá no STATICFILES_DIRS, e funcionou, isso aconteceu pq o DEBUG está True.

        Em produção vc vai usar o collectstatic e o DEBUG=False. Com isso vai dar problema devido o valor do seu STATIC_ROOT.

        Faça algo como:

        STATIC_ROOT = os.path.join(BASE_DIR, ‘static’)

        Mas isso vai fazer o local do seus assets colidir com o destino do collectstatic. Então eu sugiro que guarde os assets em um diretório “assets”, fazendo:

        STATICFILES_DIRS = (os.path.join(BASE_DIR, ‘assets’),)

Deixe uma resposta

Seu endereço de email não será publicado.