Django: "projetos" vs "aplicativos"

202

Eu tenho um "produto" bastante complexo que estou me preparando para construir usando o Django. Vou evitar o uso dos termos "projeto" e "aplicativo" neste contexto, porque não sou claro sobre o significado específico deles no Django.

Os projetos podem ter muitos aplicativos. Os aplicativos podem ser compartilhados entre muitos projetos. Bem.

Não estou reinventando o blog ou fórum - não vejo parte do meu produto reutilizável em nenhum contexto. Intuitivamente, eu chamaria esse de "aplicativo". Eu faço todo o meu trabalho em uma única pasta "app"?

Se sim ... em termos de project.appnamespace do Django , minha inclinação é usar myproduct.myproduct, mas é claro que isso não é permitido (mas o aplicativo que estou construindo é o meu projeto, e meu projeto é um aplicativo!). Portanto, sou levado a acreditar que talvez eu deva abordar o Django criando um aplicativo por modelo "significativo", mas não sei onde traçar os limites do meu esquema para separá-lo em aplicativos - tenho muitas de modelos com relações relativamente complexas.

Espero que exista uma solução comum para isso ...

Dolph
fonte
1
Os docs explicar a diferença entre "aplicação" e "projeto" aqui: docs.djangoproject.com/en/dev/ref/applications/...
guettli

Respostas:

56

O que é para você parar de usar myproduct.myproduct? O que você precisa para conseguir isso consiste basicamente em fazer isso:

django-admin.py startproject myproduct
cd myproduct
mkdir myproduct
touch myproduct/__init__.py
touch myproduct/models.py
touch myproduct/views.py

e assim por diante. Ajudaria se eu dissesse views.pyque não precisa ser chamado views.py? Desde que você possa nomear, no caminho do python, uma função (geralmente package.package.views.function_name) será manipulada. Simples assim. Todo esse material de "projeto" / "aplicativo" são apenas pacotes python.

Agora, como você deve fazer isso? Ou melhor, como posso fazer isso? Bem, se você criar uma peça significativa de funcionalidade reutilizável, como diria um editor de marcação, que é quando você cria um "app nível superior", que pode conter widgets.py, fields.py, context_processors.pyetc - todas as coisas que você pode querer importação.

Da mesma forma, se você pode criar algo como um blog em um formato bastante genérico nas instalações, pode agrupá-lo em um aplicativo, com seu próprio modelo, pasta de conteúdo estático etc., e configurar uma instância de um projeto django para usar esse conteúdo do aplicativo.

Não há regras rígidas e rápidas dizendo que você deve fazer isso, mas esse é um dos objetivos da estrutura. O fato de tudo, incluindo os modelos, permitir que você inclua a partir de alguma base comum significa que seu blog deve se encaixar perfeitamente em qualquer outra configuração, simplesmente cuidando de sua própria parte.

No entanto, para abordar sua preocupação real, sim, nada indica que você não pode trabalhar com a pasta do projeto de nível superior. É o que os aplicativos fazem e você pode fazê-lo se realmente quiser. Eu costumo não fazer isso, por várias razões:

  • A configuração padrão do Django não faz isso.
  • Muitas vezes, eu quero criar um aplicativo principal, então eu crio um, geralmente chamado website. No entanto, em uma data posterior, talvez eu queira desenvolver funcionalidades originais apenas para este site. Com o objetivo de torná-lo removível (mesmo que nunca o faça), costumo criar um diretório separado. Isso também significa que posso descartar a funcionalidade apenas desvinculando esse pacote da configuração e removendo a pasta, em vez de excluir um complexo as URLs corretas de uma pasta global urls.py.
  • Muitas vezes, mesmo quando quero fazer algo independente, ele precisa de um lugar para viver enquanto eu cuido / o faço independente. Basicamente, o caso acima, mas para coisas que pretendo tornar genéricas.
  • Minha pasta de nível superior geralmente contém algumas outras coisas, incluindo, entre outros, scripts wsgi, scripts sql etc.
  • As extensões de gerenciamento do django dependem de subdiretórios. Portanto, faz sentido nomear pacotes adequadamente.

Em resumo, o motivo pelo qual existe uma convenção é o mesmo que qualquer outra convenção - ajuda quando se trata de outras pessoas que trabalham com o seu projeto. Se eu vejo fields.py, imediatamente espero que o código contenha a subclasse do campo do django, enquanto que se eu ver inputtypes.py, talvez não seja tão claro o que isso significa sem olhar para ele.


fonte
24
+1 ... "O que é para você parar de usar myproduct.myproduct?" - O comando "startapp" do Django realmente o interrompe, suponho, como uma convenção. I como convenções, especialmente no contexto de um esforço de equipe, mas eu prefiro entender a lógica por trás deles :)
Dolph
@ Dolph ah, faz? Não o usei desde a primeira vez, porque tenho meu próprio comando para criar um projeto que primeiro cria modelos e depois gera automaticamente material CRUD para esses modelos. Ainda sim, convenções são boas. Sigo as convenções de django, apenas porque, em grande parte, elas fazem sentido.
1
Acrescentarei que o uso do mesmo nome para um projeto e um aplicativo nele também causa problemas manage.py, impedindo a importação correta das configurações do projeto. Isso aconteceu comigo e eu o resolvi refatorando o aplicativo para o efeito de myproduct_app.
precisa saber é o seguinte
89

Depois de se graduar de usar startprojecte startapp, não há nada para impedi-lo de combinar um "projeto" e "aplicativo" no mesmo pacote Python. Um projeto nada mais é do que um settingsmódulo e um aplicativo nada mais é do que um modelsmódulo - todo o resto é opcional.

Para sites pequenos, é totalmente razoável ter algo como:

site/
    models.py
    settings.py
    tests.py
    urls.py
    views.py
claymation
fonte
18
+1 Resumo: o projeto possui settings.py, o aplicativo possui models.py. Eles são da mesma estrutura de nível. Eu costumava pensar projeto é um nível mais elevado do aplicativo, acho que eu estava errado
Philip007
2
@claymation, o que deve ser incluído nas configurações (como aplicativo) para permitir 'python manage.py makemigrations' ou 'python manage.py migrate' para ver o arquivo 'models.py' no diretório 'my product'?
mlwn
1
@mlwn Percebo que estou muito atrasado em responder isso, mas estou em situação semelhante e tenho procurado muitas respostas. Para responder sua pergunta, tudo que você precisa fazer é incluir seu projeto na INSTALLED_APPSlista. Aqui está um exemplo: stackoverflow.com/a/59739912/399435
Karthic Raghupathi
@KarthicRaghupathi, Thanks .. :) bom ver comentários sendo respondidos depois de quatro anos .. cheers
mlwn 16/04
69

Tente responder à pergunta: "O que meu aplicativo faz?". Se você não puder responder em uma única frase, talvez seja possível dividi-lo em vários aplicativos com uma lógica mais limpa.

Li esse pensamento em algum lugar logo depois que comecei a trabalhar com o django e acho que faço essa pergunta a mim mesmo com bastante frequência e isso me ajuda.

Seus aplicativos não precisam ser reutilizáveis, eles podem depender um do outro, mas devem fazer uma coisa.

Esqui
fonte
8
Ainda estou lutando um pouco quando se trata de criar meu próprio aplicativo. Sinto que meu aplicativo principal é um pouco pesado, mas, ao mesmo tempo, não seria capaz de refatorá-lo em algo parecido com algo fracamente acoplado. Estou inclinado a pensar que realmente não seria uma melhoria separar minhas principais entidades principais, se elas ainda dependem muito uma da outra e não há necessidade de reutilizar ou generalizar no horizonte. Eu estou inclinando-se para "não prematuramente refactor" como uma interpretação de "não prematuramente otimizar"
acjay
8

Em caso afirmativo ... em termos do espaço de nome project.app do Django, minha tendência é usemyproduct.myproduct, mas é claro que isso não é permitido

Não há nada como não permitido. É seu projeto, ninguém está te restringindo. É aconselhável manter um nome razoável.

Não vejo parte do meu produto reutilizável em nenhum contexto. Intuitivamente, eu chamaria esse de "aplicativo". Eu faço todo o meu trabalho em uma única pasta "app"?

Em um projeto geral do django, existem muitos aplicativos (aplicativos de contribuição) que são realmente usados ​​em todos os projetos.

Digamos que seu projeto mainexecute apenas uma tarefa e tenha apenas um aplicativo (o nomeio como o projeto gira em torno dele e dificilmente pode ser conectado). Este projeto também ainda usa alguns outros aplicativos em geral.

Agora, se você disser que seu projeto está usando apenas o app ( INSTALLED_APPS='myproduct'), então, para que serve projectdefini-lo project.app, acho que você deve considerar alguns pontos:

  • Existem muitas outras coisas que o código que não seja o aplicativo em um projeto lida (arquivos estáticos básicos, modelos básicos, configurações ... ou seja, fornece a base).
  • Na abordagem geral project.app, o django define automaticamente o esquema sql a partir dos modelos.
  • Seu projeto seria muito mais fácil de ser construído com a abordagem convencional.
  • Você pode definir alguns nomes diferentes para URLs, visualizações e outros arquivos como desejar, mas não vejo a necessidade.
  • Você pode precisar adicionar algumas aplicações no futuro, o que seria muito fácil com os projetos de django convencionais que, caso contrário, pode se tornar igualmente ou mais difícil e entediante.

No que diz respeito à maior parte do trabalho que está sendo feito no aplicativo, acho que é o caso da maioria dos projetos de django.

crodjer
fonte
1
+1, esp para a mainconvenção - isso faz muito sentido para mim para um projeto original como este. Eu pretendo adicionar aplicativos "reutilizáveis" posteriormente, mas isso está muito além do meu foco no momento.
Dolph
2

Aqui os criadores do Django apontam essa diferença eles mesmos . Eu acho que é bom pensar nos aplicativos, pois eles devem ser reutilizáveis em outros projetos . Também uma boa maneira de pensar sobre os aplicativos no Django fornece aplicativos da web modernos.

Imagine que você está criando um grande aplicativo dinâmico da Web com base em JavaScript .

Você pode criar então no django App chamado, por exemplo, "FrontEnd" <- no aplicativo fino, você exibirá o conteúdo.

Em seguida, você cria alguns aplicativos de back-end. Por exemplo, o aplicativo chamado "Comentários" que armazenará os comentários do usuário. E o aplicativo "Comentários" não exibirá nada em si. Será apenas uma API para solicitações AJAX do seu site JS dinâmico .

Dessa forma, você sempre pode reutilizar o aplicativo "Comentários". Você pode torná-lo de código aberto sem abrir o código-fonte do projeto inteiro. E você mantém a lógica limpa do seu projeto.

Qback
fonte