Iniciando um projeto Django pronto para colaboração e escala
Há algumas coisas que eu particularmente faço quando inicio um novo projeto em Django, resolvi compartilhá-las aqui porque podem talvez ajudar outros desenvolvedores a obter sucesso com seus projetos.
1 - A estrutura de diretórios do projeto
Uma boa estrutura de diretórios irá permitir que você lide com o código e suas depenências de maneira facilitada, pessoalmente eu uso a estrutura seguinte:
Todo o meu código está disponível em um workspace, dentro do subdiretório com o nome do projeto, que por sua vez, possui um subdiretório de nome "src". Do mesmo modo, no diretório do projeto há o ambiente virtual criado para gerir as versões da linguagem e suas dependências de software. Dessa maneira os ambientes ficam mais fáceis de serem localizados e ao mesmo tempo não interferem nos arquivos fontes do projeto.
2 - Sempre utilize um ambiente virtual (virtualenv):
Essa já é uma coisa mandatória para projetos escritos em Python mas não custa falar. Um ambiente virtual é uma 'sandbox' que isola sua aplicação e suas depenências do sistema operacional. Por exemplo, se dez aplicações diferentes escritas em python estiverem rodando no mesmo contêiner, cada uma delas utilizando uma versão diferente de python e de dependências em comum, sem um isolamento por ambiente virtual em algum momento haverá conflitos entre as versões instaladas.
Para criar e ativar um ambiente virtual com o virtualenv é bem simples:
Uma outra coisa que sempre faço para facilitar minha vida é criar um alias no meu .bash_aliases para ativar o projeto com uma linha de comando.
3 - Mantenha dados sensíveis fora do repositório:
O arquivo settings.py do Django tem muita informação sensível ao projeto. Colocar essas informações em variáveis de ambiente do sistema operacional é uma boa ideia por dois motivos:
- Os dados podem mudar de acordo o lugar onde estejam rodando;
- Dados sensíveis sempre precisam ser mantidos em segredo;
Para fazer isso são necessários dois arquivos: env.py e env.sample.py.
- O arquivo env.py será responsável por conter uma tupla com as variáveis de ambiente a serem definidas e seus valores preenchidos com os dados sensíveis. Sob hipótese alguma este arquivo deve estar adicionado no seu repositório git;
- O arquivo env.sample.py será responsável por conter uma tupla com as variáveis de ambiente sem os valores definidos, agindo assim, como um guia para novos desenvolvedores que cheguem ao projeto. Este arquivo deve estar adicionado no seu repositório;
Primeiramente vamos criar o arquivo de exemplo env.sample.py:
Agora vamos criar nosso .gitignore na raiz do projeto
O arquivo .gitgnore precisará conter instruções para que o nosso repositório ignore a adição do arquivo de variáveis env.py.
Agora, precisamos fazer mais duas etapas:
- Copiar o arquivo env.sample.py para env.py e preencher todas as variáveis com os dados sensíveis;
- Carregar o arquivo de variáveis como variáveis do sistema operacional no script em project_name/__init__.py
Finalmente, precisaremos substituir os dados sensíveis no nosso arquivo settings.py, como no exemplo abaixo:
4 - Fazendo escolhas sábias sobre versões do Python e do Django:
No site do Django Framework, na página de download, podemos ver a imagem abaixo com o demonstrativo do roadmap do projeto:
Baseado nessa imagem, podemos concluir a respeito de versões para um projeto:
- Python 2.x is já era. O suporte para essa versão do python finalizou com o também já finalizado Django 1.11 LTS;
- É uma boa prática manter todos os desenvolvedores com a mesma versão 3.x do Python;
- Sempre preferir a última versão LTS para projetos em produção salvará você de muita dor de cabeça;
- Sempre ter em mente o lançamento da nova LTS, realizar upgrades quando necessário e ficar de olho nas datas de suporte e correção de bugs também é importante;
5 - Crie uma política forte para seu .gitignore:
Abaixo segue um exemplo de arquivo .gitignore comum aos meus projetos em Django.
Em resumo, tudo o que for automático, coletado ou gerado, possa bagunçar o desenvolvimento ou cause confusão no time precisa estar aqui:
Coisas como:
- Variáveis de ambiente contendo dados sensíveis;
- Arquivos compilados do CPython. *.pyc;
- Todos os arquivos de mídia e estáticos coletados;
- Arquivos de configuração de workspace das IDE's;
- Arquivos de cache e diretórios de cache gerados pela execução do projeto;
- Arquivos de migração;
Antes que alguém atire a primeira pedra saibam o motivo. Muitas pessoas mantém os seus arquivos de migração dentro do repositório mas eu não.
Sou um filho rebelde, pois, a documentação oficial do Django recomenda um outro ponto de vista:
The migration files for each app live in a “migrations” directory inside of that app, and are designed to be committed to, and distributed as part of, its codebase. You should be making them once on your development machine and then running the same migrations on your colleagues’ machines, your staging machines, and eventually your production machines.
Em minha opinião, arquivos de migração são códigos gerados e devem ficar fora do repositório; Imagine por exemplo, que sua aplicação em produção tenha centenas de bancos de dados, cada um para um cliente. Imagine ainda que em um determinado model haja um campo models.FileField para guardar um arquivo.
Ora, como os FileField geram nas migrations paths absolutos para o campo "upload_to", a migration irá conter o path do workspace do desenvolvedor que a gerou. Assim, quando outro desenvolvedor pegar o código terá que mergear essa informação na sua máquina, por sua vez, também o será em produção. Isso significa que sem necessidade alguma você terá que migrar centenas de bancos de dados toda vez que alguém rodar um simples makemigrations
Obviamente, esse problema não ocorrerá quando todos os desenvolvedores utilizarem um container como workspace que será disponibilizado também em produção. Mas na minha experiência as aplicações tem funcionado melhor com migrations criadas somente na hora do deploy, quando realmente houver alterações de dados.
Essas são algumas dicas que gostaria de passar para vocês a respeito de iniciar um projeto focado em produtividade e escalabilidade,
Caso tenham dúvidas ou desejem perguntar algo podem usar os comentários,