Prática recomendada para a estrutura de diretório de trabalho do projeto Django


174

Eu sei que não há realmente nenhum caminho certo. No entanto, descobri que é difícil criar uma estrutura de diretórios que funcione bem e permaneça limpa para todos os desenvolvedores e administradores. Existe alguma estrutura padrão na maioria dos projetos no github. Mas não mostra uma maneira de organizar outros arquivos e todos os projetos no PC.

Qual é a maneira mais conveniente de organizar todos esses diretórios na máquina de desenvolvimento? Como você os nomeia e como você os conecta e implanta no servidor?

  • projetos (todos os projetos em que você está trabalhando)
  • arquivos de origem (o próprio aplicativo)
  • cópia de trabalho do repositório (eu uso o git)
  • ambiente virtual (prefiro colocá-lo próximo ao projeto)
  • raiz estática (para arquivos estáticos compilados)
  • raiz da mídia (para arquivos de mídia carregados)
  • Leia-me
  • LICENÇA
  • documentos
  • esboços
  • exemplos (um projeto de exemplo que usa o aplicativo fornecido por este projeto)
  • banco de dados (caso o sqlite seja usado)
  • qualquer outra coisa que você normalmente precise para um trabalho bem-sucedido no projeto

Os problemas que eu quero resolver:

  • Bons nomes de diretórios para que seus objetivos sejam claros.
  • Mantendo todos os arquivos do projeto (incluindo virtualenv) em um único local, para que eu possa copiar, mover, arquivar, remover com facilidade todo o projeto ou estimar o uso do espaço em disco.
  • Criar várias cópias de alguns conjuntos de arquivos selecionados, como aplicativo inteiro, repositório ou virtualenv, mantendo uma cópia única de outros arquivos que não quero clonar.
  • Implantando o conjunto correto de arquivos no servidor, basta sincronizar novamente um diretório.

Respostas:


257

Existem dois tipos de "projetos" do Django que tenho no meu ~/projects/diretório, ambos com uma estrutura um pouco diferente:

  • Sites independentes
  • Aplicações conectáveis

Site independente

Projetos principalmente privados, mas não precisam ser. Geralmente é assim:

~/projects/project_name/

docs/               # documentation
scripts/
  manage.py         # installed to PATH via setup.py
project_name/       # project dir (the one which django-admin.py creates)
  apps/             # project-specific applications
    accounts/       # most frequent app, with custom user model
    __init__.py
    ...
  settings/         # settings for different environments, see below
    __init__.py
    production.py
    development.py
    ...

  __init__.py       # contains project version
  urls.py
  wsgi.py
static/             # site-specific static files
templates/          # site-specific templates
tests/              # site-specific tests (mostly in-browser ones)
tmp/                # excluded from git
setup.py
requirements.txt
requirements_dev.txt
pytest.ini
...

Configurações

As principais configurações são as de produção. Outros arquivos (por exemplo staging.py, development.py) simplesmente importam tudo production.pye substituem apenas as variáveis ​​necessárias.

Para cada ambiente, existem arquivos de configurações separados, por exemplo. produção, desenvolvimento. Em alguns projetos, também tenho as configurações de teste (para test runner), teste (como uma verificação antes da implantação final) e heroku (para implantação no heroku).

Exigências

Prefiro especificar requisitos em setup.py diretamente. Somente aqueles necessários para o ambiente de desenvolvimento / teste em que eu trabalho requirements_dev.txt.

Alguns serviços (por exemplo, heroku) precisam ter requirements.txtno diretório raiz.

setup.py

Útil ao implantar projeto usando setuptools. Acrescenta manage.pya PATH, para que eu possa executar manage.pydiretamente (em qualquer lugar).

Aplicativos específicos do projeto

Eu costumava colocar esses aplicativos no project_name/apps/diretório e importá-los usando importações relativas.

Arquivos de templates / static / locale / tests

Coloquei esses modelos e arquivos estáticos no diretório global de modelos / estático, não dentro de cada aplicativo. Esses arquivos geralmente são editados por pessoas que não se importam com a estrutura de código do projeto ou com o python. Se você é um desenvolvedor de pilha completa trabalhando sozinho ou em uma equipe pequena, pode criar modelos / diretório estático por aplicativo. É realmente apenas uma questão de gosto.

O mesmo se aplica à localidade, embora às vezes seja conveniente criar um diretório local.

Normalmente, os testes são melhores para colocar dentro de cada aplicativo, mas geralmente há muitos testes funcionais / de integração que testam mais aplicativos trabalhando juntos, portanto o diretório global de testes faz sentido.

Diretório tmp

Há um diretório temporário na raiz do projeto, excluído do VCS. É usado para armazenar arquivos estáticos / de mídia e banco de dados sqlite durante o desenvolvimento. Tudo no tmp pode ser excluído a qualquer momento sem problemas.

Virtualenv

Eu prefiro virtualenvwrappere coloque todos os venvs no ~/.venvsdiretório, mas você pode colocá-los dentro tmp/para mantê-los juntos.

Modelo de projeto

Eu criei um modelo de projeto para esta configuração, django-start-template

Desdobramento, desenvolvimento

A implantação deste projeto é a seguinte:

source $VENV/bin/activate
export DJANGO_SETTINGS_MODULE=project_name.settings.production
git pull
pip install -r requirements.txt

# Update database, static files, locales
manage.py syncdb  --noinput
manage.py migrate
manage.py collectstatic --noinput
manage.py makemessages -a
manage.py compilemessages

# restart wsgi
touch project_name/wsgi.py

Você pode usar em rsyncvez de git, mas ainda assim precisa executar lotes de comandos para atualizar seu ambiente.

Recentemente, criei o [django-deploy][2]aplicativo, o que me permite executar um único comando de gerenciamento para atualizar o ambiente, mas eu o usei apenas para um projeto e ainda estou experimentando.

Esboços e rascunhos

Rascunho de modelos que coloco dentro do templates/diretório global . Eu acho que se pode criar uma pasta sketches/na raiz do projeto, mas ainda não a usou.

Aplicação plugável

Esses aplicativos geralmente são preparados para publicar como código aberto. Eu peguei o exemplo abaixo do django-forme

~/projects/django-app/

docs/
app/
tests/
example_project/
LICENCE
MANIFEST.in
README.md
setup.py
pytest.ini
tox.ini
.travis.yml
...

O nome dos diretórios é claro (espero). Coloquei os arquivos de teste fora do diretório do aplicativo, mas isso realmente não importa. É importante fornecer READMEe setup.py, portanto, o pacote é facilmente instalado pip.


Obrigado! Eu gosto da sua estrutura. Isso me deu idéias úteis. Bons pontos sobre o uso do setup.py para requisitos e a instalação do manage.py no PATH. Poderia mostrar como você faz a última coisa? Também é um bom argumento sobre o diretório 'tmp'. Prefiro chamá-lo de 'local', para que eu possa ter 'env', 'tmp' e qualquer outra coisa dentro. Isso resolve o problema de ter muitos negócios com o gitignore. Um novo problema é que esse nome está muito próximo de 'localidade'. Talvez faça sentido mover 'locale' para o aplicativo principal 'project_name', sem ter certeza. Só não quero mudar a estrutura por causa do mau nome. Alguma sugestão?
raacer 5/05

Ao usar o setup.py, adicione o scriptsargumento da palavra-chave: github.com/elvard/django-start-template/blob/master/project/… Gosto tmpporque sugere "algo temporário" que pode ser removido a qualquer momento. O localediretório de nível superior não é necessário, você pode colocá-lo em qualquer lugar. Eu apenas gosto que seja consistente com diretórios estáticos / modelos.
Tomáš Ehrlich 5/05

Meu requisito para a capacidade de fazer várias cópias dos arquivos de origem sem copiar outros arquivos não foi resolvido diretamente. Mas o objetivo ainda pode ser arquivado usando git checkoutou excluindo apenas um diretório 'tmp' ao clonar o diretório do projeto. Parece que sua estrutura atende a todos os requisitos e é claro o suficiente para ser usado regularmente, sem qualquer dúvida. Estou aceitando sua resposta. Obrigado.
raacer

Obrigado. Ainda não entendo o que você entende por "capacidade de fazer várias cópias dos arquivos de origem sem copiar outros arquivos". Comando Tweaked rsync faria, mas isso não é provavelmente o que você quer dizer ...
Tomáš Ehrlich

Geralmente crio dir srcdentro da raiz do projeto. Esta é a cópia de trabalho dos arquivos de origem e a raiz do repositório git. Posso fazer várias cópias deste diretório - src, src.bak, src_tmpe assim por diante. Outros diretórios não-repo como env, tmp, media, backupresidir no mesmo nível. Para que eu possa, a cp -r src src.bakqualquer momento, fazer experimentos com o git ou comparar versões com ferramentas externas. Enquanto você tem arquivos locais dentro do seu repositório, eu tenho repositório dentro dos meus diretórios de arquivos locais (vice-versa). O melhor nome do meu srcdiretório é repo.
raacer

19

Minha resposta é inspirada em minha própria experiência de trabalho, e principalmente no livro Two Scoops of Django, que eu recomendo, e onde você pode encontrar uma explicação mais detalhada de tudo. Apenas responderei a alguns pontos e qualquer melhoria ou correção será bem-vinda. Mas também pode haver maneiras mais corretas para atingir o mesmo objetivo.

Projetos
Eu tenho uma pasta principal no meu diretório pessoal, onde mantenho todos os projetos nos quais estou trabalhando.

Arquivos de origem
Eu pessoalmente uso a raiz do projeto django como raiz do repositório dos meus projetos. Mas no livro é recomendado separar as duas coisas. Penso que esta é uma abordagem melhor, por isso espero começar a fazer alterações progressivamente nos meus projetos.

project_repository_folder/
    .gitignore
    Makefile
    LICENSE.rst
    docs/
    README.rst
    requirements.txt
    project_folder/
        manage.py
        media/
        app-1/
        app-2/
        ...
        app-n/
        static/
        templates/
        project/
            __init__.py
            settings/
                __init__.py
                base.py
                dev.py
                local.py
                test.py
                production.py
            ulrs.py
            wsgi.py

Repository
Git ou Mercurial parecem ser os sistemas de controle de versão mais populares entre os desenvolvedores do Django. E os serviços de hospedagem mais populares para backups do GitHub e Bitbucket .

Ambiente virtual
Eu uso virtualenv e virtualenvwrapper. Depois de instalar o segundo, você precisa configurar seu diretório de trabalho. O meu está no meu diretório / home / envs , como recomendado no guia de instalação do virtualenvwrapper. Mas não acho que o mais importante é onde é colocado. O mais importante ao trabalhar com ambientes virtuais é manter o arquivo requirements.txt atualizado.

pip freeze -l > requirements.txt 


Pasta Projeto de raiz estática


Pasta Projeto Raiz da Mídia


Raiz README do repositório


Raiz do repositório da LICENÇA


Raiz do Repositório de Documentos . Estes pacotes python podem ajudá-lo a facilitar a manutenção de sua documentação:

Esboços

Exemplos

Base de dados


Obrigado por compartilhar sua experiência. Há muitos diretórios 'projeto *' em sua estrutura. Você provavelmente não usa esses nomes na vida real, certo? Digamos que temos um projeto 'todo'. Como você nomeia esses diretórios nesse caso? O problema que vejo na sua estrutura atual é misturar repositório com arquivos que não são do repositório (como você observou acima). Pode ser irritante adicionar qualquer lixo ao .gitignore, não é? Outra coisa duvidosa é manter o ambiente distante do projeto em si. Isso faz sentido? Por que não criar ~ / docs, ~ / static e assim por diante? Até o git gosta de ficar perto dos arquivos de origem.
raacer

Eu os nomearia: "todo_project" -> todo -> todo (ou talvez todoapp). Eu acho que é importante estar na pasta do repositório na raiz da hierarquia do diretório. Mas, é apenas a minha opinião. Sobre o diretório do ambiente, quando você precisa configurar o ambiente de produção, basta digitar: pip install -U -r requirements.txt. Mas, como eu disse, não há uma solução para tudo.
CR

Portanto, o caminho para o aplicativo principal é "projects / todo_project / todo / todo". A palavra "projetos" é repetida duas vezes e a palavra "todo" é repetida três vezes. Parece "projetos / projeto / meu_projeto / projeto_dir / projeto / projeto". Os nomes não são muito claros. Este é um dos principais problemas que estou tentando resolver na minha estrutura de diretórios. Quero nomear os diretórios para facilitar o entendimento da hierarquia. E quanto à raiz do repositório, você poderia explicar por que é importante? Você também pode explicar o que é bom em manter envs fora do diretório principal do projeto?
raacer

13

Não gosto de criar um novo settings/diretório. Simplesmente adiciono arquivos nomeados settings_dev.pye settings_production.pynão preciso editar o arquivo BASE_DIR. A abordagem abaixo aumenta a estrutura padrão em vez de alterá-la.

mysite/                   # Project
    conf/
        locale/
            en_US/
            fr_FR/
            it_IT/
    mysite/
        __init__.py
        settings.py
        settings_dev.py
        settings_production.py
        urls.py
        wsgi.py
    static/
        admin/
            css/           # Custom back end styles
        css/               # Project front end styles
        fonts/
        images/
        js/
        sass/
    staticfiles/
    templates/             # Project templates
        includes/
            footer.html
            header.html
        index.html
    myapp/                 # Application
        core/
        migrations/
            __init__.py
        templates/         # Application templates
            myapp/
                index.html
        static/
            myapp/
                js/  
                css/
                images/
        __init__.py
        admin.py
        apps.py
        forms.py
        models.py
        models_foo.py
        models_bar.py
        views.py
    templatetags/          # Application with custom context processors and template tags
        __init__.py
        context_processors.py
        templatetags/
            __init__.py
            templatetag_extras.py
    gulpfile.js
    manage.py
    requirements.txt

Eu acho que isto:

    settings.py
    settings_dev.py
    settings_production.py

é melhor que isso:

    settings/__init__.py
    settings/base.py
    settings/dev.py
    settings/production.py

Este conceito também se aplica a outros arquivos.


Eu costumo colocar node_modules/e bower_components/no diretório do projeto dentro da static/pasta padrão .

Às vezes, um vendor/diretório para Submodules Git, mas geralmente eu os coloco na static/pasta.


4

Aqui está o que eu sigo no Meu sistema.

  1. Todos os Projetos : Existe um diretório de projetos em minha casa pasta ie ~/projects. Todos os projetos ficam dentro dele.

  2. Projeto Individual : Sigo um modelo de estrutura padronizado usado por muitos desenvolvedores chamado django-skel para projetos individuais. Basicamente, ele cuida de todos os seus arquivos estáticos e de mídia e tudo.

  3. Ambiente virtual : tenho uma pasta virtualenvs em minha casa para armazenar todos os ambientes virtuais no sistema, ou seja ~/virtualenvs. Isso me dá uma flexibilidade de saber quais são os ambientes virtuais que tenho e que posso usar facilmente

Os três acima são as principais partições do Meu ambiente de trabalho.

Todas as outras partes mencionadas dependem principalmente do projeto para o projeto (por exemplo, você pode usar bancos de dados diferentes para projetos diferentes). Portanto, eles devem residir em seus projetos individuais.


Obrigado. Pode ser irritante adicionar qualquer lixo ao .gitignore ao misturar o repositório com arquivos que não são do repositório. Não é? Alguns dos meus projetos têm até dez ou mais desses arquivos e diretórios, o que faz com que seja um problema real para mim. Outra coisa duvidosa é manter o ambiente distante do projeto em si. Qual é a flexibilidade dessa solução? Por que não criar ~ / docs, ~ / static e assim por diante? Até o git gosta de ficar perto dos arquivos de origem. Eu pensei que a flexibilidade é quando eu posso apenas copiar / mover / arquivo / remover diretório do projeto inteiro, incluindo virtualenv e pode manter várias envs dentro de um projeto facilmente
raacer

4

De acordo com o Django Project Skeleton, a estrutura de diretórios apropriada que pode ser seguida é:

[projectname]/                  <- project root
├── [projectname]/              <- Django root
   ├── __init__.py
   ├── settings/
      ├── common.py
      ├── development.py
      ├── i18n.py
      ├── __init__.py
      └── production.py
   ├── urls.py
   └── wsgi.py
├── apps/
   └── __init__.py
├── configs/
   ├── apache2_vhost.sample
   └── README
├── doc/
   ├── Makefile
   └── source/
       └── *snap*
├── manage.py
├── README.rst
├── run/
   ├── media/
      └── README
   ├── README
   └── static/
       └── README
├── static/
   └── README
└── templates/
    ├── base.html
    ├── core
       └── login.html
    └── README

Consulte https://django-project-skeleton.readthedocs.io/en/latest/structure.html para obter a estrutura de diretórios mais recente.


7
Eu odeio a abordagem [projectname] / [projectname])!
raacer

1
O django-project-skeleton não é "a documentação do Django". Seria mais preciso dizer "Conforme django-project-skeleton, ...".
David Winiecki

0

Você pode usar o https://github.com/Mischback/django-project-skeleton repository.

Execute o comando abaixo:

$ django-admin startproject --template=https://github.com/Mischback/django-project-skeleton/archive/development.zip [projectname]

A estrutura é algo como isto:

[projectname]/                  <- project root
├── [projectname]/              <- Django root
   ├── __init__.py
   ├── settings/
      ├── common.py
      ├── development.py
      ├── i18n.py
      ├── __init__.py
      └── production.py
   ├── urls.py
   └── wsgi.py
├── apps/
   └── __init__.py
├── configs/
   ├── apache2_vhost.sample
   └── README
├── doc/
   ├── Makefile
   └── source/
       └── *snap*
├── manage.py
├── README.rst
├── run/
   ├── media/
      └── README
   ├── README
   └── static/
       └── README
├── static/
   └── README
└── templates/
    ├── base.html
    ├── core
       └── login.html
    └── README
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.