Dúvidas de Boras Práticas Django

51 views
Skip to first unread message

Paulo Dev

unread,
Feb 19, 2021, 9:23:49 AM2/19/21
to Python Brasil
Olá Pessoal, 
Preciso de uma orientação dos mais experientes em projetos grandes.

Eu desenvolvo software a 30 anos, tive uma janela de 8 anos sem desenvolver e a 1 ano peguei duas grandes plataformas e resolvi desenvolve-las em Python/Django.

Agora que os projetos já tem corpo estou desconfortável com a estrutura do Django: models.py, admin.py, utils.py, urls.py e views.py

Para cada app instalado o django cria esses arquivos e acabei distribuindo a programação dentro desses programas. A View virou um programa gigante com diversas funções. Utils tem pouca coisa. Mas o que mais me incomoda são os models (tabelas) distribuídas nos apps. Recentemente tive um problema com inclusão circular, o que me obrigou a mudar uma tabela de model.

Eu tenho algumas dúvidas, se puderem me ajudar eu seria imensamente grato:

1 - Eu já ouvi falar que dentro da View só deve ter view e não códigos grandes. E também em alguns programas que eu vi no git, tem um main.py... qual é a melhor maneira de distribuir as funcionalidades pelos fontes?

2 - Programas grandes deixam o sistema lento? Pergunto porque muitas funcionalidades chamam somente pequenas linhas de fontes grantes.

3 - Eu posso escolher colocar todas as tabelas dentro do core/model.py ? Sem fazer a distribuição nos models dentro dos apps?

4 - É comum criar diversos apps no programa?

Se alguém tiver uma documentação ou uma orientação de boas práticas para sistemas grandes em python que eu já deveria conhecer e puder me orientar agradeço muito

Grato pelo apoio

Nilton C S

unread,
Feb 19, 2021, 9:39:36 AM2/19/21
to python...@googlegroups.com
Eu sou novato em desenvolvimento de sistemas com Python e Flask. Não fui pra Django ainda. A arquitetura de software é algo ajuda a simplificar a complexidade de um sistema grande. Eu comprei um livro chamado Python levado a sério. Não li ainda, mas tópicos avançados para projetos grandes. 

--
--
------------------------------------
Grupo Python-Brasil
https://wiki.python.org.br/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com
---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/python-brasil/527224fd-ba3b-48f0-87ed-fec539c53238n%40googlegroups.com.

Fabio C. Barrionuevo da Luz

unread,
Feb 19, 2021, 9:50:49 AM2/19/21
to python...@googlegroups.com
>> 1 - Eu já ouvi falar que dentro da View só deve ter view e não códigos grandes. E também em alguns programas que eu vi no git, tem um main.py... qual é a melhor maneira de distribuir as funcionalidades pelos fontes?

Views devem ser pequenas sempre quando possivel. Geralmente as regras de negocio estão implementadas nos Queryset, Managers, e nos Models quando isso faz sentido.

>> 2 - Programas grandes deixam o sistema lento? Pergunto porque muitas funcionalidades chamam somente pequenas linhas de fontes grantes.
Não necessariamente. Você deve evitar código macarrônico. Você deve ser testes automatizados. Se for muito complexo escrever um teste para o seu codigo, pode ser que seu codigo esteja fazendo mais coisas do que deveria e esta complexo demais... dividir para conquistar.


>> 3 - Eu posso escolher colocar todas as tabelas dentro do core/model.py ? Sem fazer a distribuição nos models dentro dos apps?

Pode se isso fizer sentido para você e para o projeto.


>> 4 - É comum criar diversos apps no programa?

Sim. Mas geralmente uma app deve ser projetada para funcionar de maneira quase independente das outras, quase de maneira autocontida.

Dito isto, acho que muitas das suas duvidas podem ser respondidas pelo curso do Henrique Bastos https://henriquebastos.net/produtos/welcome-to-the-django
(acho que já fechou as inscrições. Geralmente é uma ou duas turmas por ano só... Sugiro entrar em contato com ele pelo whatsapp que tem no final da pagina).



--
--
------------------------------------
Grupo Python-Brasil
https://wiki.python.org.br/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com
---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/python-brasil/527224fd-ba3b-48f0-87ed-fec539c53238n%40googlegroups.com.


--
Fábio C. Barrionuevo da Luz
Palmas - Tocantins - Brasil - América do Sul


Blog colaborativo sobre Python e tecnologias Relacionadas, mantido totalmente no https://github.com/pythonclub/pythonclub.github.io .

Todos são livres para publicar. É só fazer fork, escrever sua postagem e mandar o pull-request. Leia mais sobre como publicar em README.md e contributing.md.
Regra básica de postagem:
"Você" acha interessante? É útil para "você"? Pode ser utilizado com Python ou é útil para quem usa Python? Está esperando o que? Publica logo, que estou louco para ler...

Jorge Miguel

unread,
Feb 19, 2021, 9:54:02 AM2/19/21
to python...@googlegroups.com
Paulo bom dia!

Vou falar da MINHA experiência com Django( Não tome isso como verdade, mas eu gosto desse formato)

Respondendo as suas dúvidas >
1 - Segundo as boas práticas, o correto é ter models grandes (ou Fat Models) e views com menos codigo, não se deve ter regras de negócio nas views. EU particularmente gosto de criar o utils.py ou service.py (tanto faz o nome) e crio os métodos que serão necessários para o funcionamento de alguma regra de negócio ou algo do tipo.

2 - Isso depende muito, mas acredito que a infra onde esse código está rodando pode ter mais impacto sobre a velocidade. Mas a refatoração é sempre bem vinda para resolver esses pontos de lentidão que forem encontrados.

3 - Nos projetos que costumo trabalhar sempre faço dessa forma. Separo em uma app core todas as minhas entidades de banco. Nas outras apps é só importar o models.py de app/core. 

4 - Dependendo do que você está desenvolvendo, é comum que a quantidade de apps cresça.

Depois da uma olhada nesse link, tem algumas informações interessantes > https://django-best-practices.readthedocs.io/en/latest/applications.html

Paulo Dev

unread,
Feb 19, 2021, 11:48:11 AM2/19/21
to python...@googlegroups.com

Jorge, Miguel e Nilton,

 

Grato pelo tempo de vocês em me ajudar com esse assunto.

 

Abraço!

zica...@gmail.com

unread,
Feb 19, 2021, 2:29:14 PM2/19/21
to Python Brasil
o Renzo tem um curso muito bom...

Eric Chiesse

unread,
Feb 20, 2021, 10:55:52 AM2/20/21
to python...@googlegroups.com
Oi Paulo

Pela descrição que você está dando do problema, me pareceu que você está tendo problemas mais com modelagem do que com o Django em si.

Eu resolvo o problema de dependências cíclicas estruturando as camadas da minha aplicação. Significa que eu tenho apps de infra e suporte, apps que descrevem o meu domínio (lógica de negócio) e apps que provêem serviços para o usuário (camada de aplicação). E dentro de cada app sigo a mesma filosofia para criar os módulos.
A regra básica da arquitetura em camadas é que as camadas de baixo não podem acessar (nem conhecer) nada das camadas superiores.

Sobre suas dúvidas:

1 - Views
Nas views eu evito bastante ficar definindo minhas queries. 90% do tempo uma query feita na view é algo importante para minha modelagem de domínio e eu transfiro para o model.
Exemplo
Imagine que quero formatar de forma diferente quando um checklist estiver concluido. Esse é um código que faria isso:
# Model:
class Checklist(Model):
    name = CharField()
   
class Item(Model):
    name = CharField()
    checked = BooleanField()
    checklist = ForeignKey(Checklist, on_delete = CASCADE)
   
   
# View:
def checklist_show(request, id):
    checklist = Checklist.objects.get(id=id)
   
    # Se o checklist estiver completo quero atribuir um estilo no titulo:
    checklist_complete = True
    for item in checklist.item_set.all():
        if not item.checked:
            checklist_complete = False
            break
           
    context = {
        'checklist': checklist,
        'title_class': 'title-complete' if checklist_complete else 'title',
    }
   
    return render(request, 'checklist.html', context)

O problema com o código acima é que a verificação se o checklist está completo ou não foi feita localmente na view. Além de poluir esta view, se eu precisar verificar novamente vou ter duplicação de código e mais uma view poluida.
Como a verificação se o checklist está completo é importante no meu domínio, preciso mover essa verificação para o model:
# Model:
class Checklist(Model):
    name = CharField()

    def is_complete(self):
        checklist_complete = True
        for item in self.item_set.all():
            if not item.checked:
                checklist_complete = False
                break
        return checklist_complete

   
class Item(Model):
    name = CharField()
    checked = BooleanField()
    checklist = ForeignKey(Checklist, on_delete = CASCADE)
   
   
# View:
def checklist_show(request, id):
    checklist = Checklist.objects.get(id=id)
   
    # Se o checklist estiver completo quero atribuir um estilo no titulo:
    context = {
        'checklist': checklist,
        'title_class': 'title-complete' if checklist.is_complete() else 'title',
    }
   
    return render(request, 'checklist.html', context)


Nessa segunda versão a view fica bem mais simples e o model fica mais expressivo. Se eu quiser verificar em outra view basta usar o método.
Isso repetido com várias operações vai diminuindo consideravelmente o tamanho da view.

2 - Performance
O fato de um sistema ser grande em si não quer dizer muita coisa. O que vai tornar seu programa lendo é:
 - Se ele faz muito processamento
 - Se ele acessa recursos lentos (muitas requisições a outros servidores, retorna queries grandes, lê arquivos muito grandes). Se ele não faz nada disso não deveria ser lento.
A melhor maneira de entender é fazendo um profiling do teu sistema.

3 e 4 - Divisão das tabelas entre apps
Eu normalmente quando começo um projeto coloco tudo no mesmo app. Mas conforme aprendo com o projeto começo a organiza-lo melhor.
Por exemplo, é muito vantajoso ter um app isolado para cuidar apenas das vendas de um site. E ter outro app para cuidar do cadastro de funcionários.
No caso do app de vendas vc pode ter tua tabela de produtos e o registro das vendas em si e esse app se plugar de maneira harmônica na tua aplicação. Fica organizado e isolado o que é muito bom.
Outra vantagem é que vc potencialmente poderá manter esse app separadamente e usá-lo em outros projetos se quiser.
O que vai determinar o sucesso dessa separação é onde encaixar o app (em qual camada da tua arquitetura) para vc não ter problemas com dependências circulares.
É importante montar um diagrama mostrando quem provê e quem consome serviços.

Te recomendo o livro "Domain Driven Design". Foi de onde tirei boa parte das ideias que eu falei.

Se quiser trocar uma ideia ao vivo me chama no discord: https://discord.gg/7Ndjjvg

Sucesso e boa sorte

---
Eric Chiesse


--

Marco de Aguiar

unread,
Feb 20, 2021, 1:28:06 PM2/20/21
to Python Brasil
Se um arquivo ficar muito grande é possível transformar um arquivo em modulo sem fazer refactor no resto da code base.
Você pode criar um pasta com o mesmo nome do arquivo, separar as classes uma em cada arquivo e no __init__.py do modulo importar as classes que estão em cada arquivo.

Por exemplo:

models.py contém User, Product, Sale

Você cria os arquivos (com as suas devidas classes):
models/user.py 
models/product.py
models/sale.py

E no models/__init__.py você põe os imports:
from app.models.user import User
from app.models.product import Product
from app.models.sale import Sale

Fora isso o pessoal ja falou tudo. Quanto a divisão entre apps, faço como o Eric falou: começo om tudo centralizado se não tenho muito a ideia de como vai ficar a estrutura final. Com o passar do tempo separado os apps por funcionalidade, meio que como um macro Single Responsability.

Abraço,
Marco Aguiar
Reply all
Reply to author
Forward
0 new messages