Criar comandos customizados no Django pode ser uma habilidade poderosa para desenvolvedores que desejam automatizar tarefas repetitivas ou criar funcionalidades específicas para suas aplicações. Neste artigo, vamos explorar como você pode criar comandos customizados no Django para tornar seu desenvolvimento mais eficiente e flexível.
Por que criar comandos customizados no Django?
Antes de mergulharmos na criação dos comandos customizados, é importante entender por que isso pode ser útil. Aqui estão alguns motivos pelos quais você pode querer criar seus próprios comandos no Django:
- Automatização de tarefas: comandos customizados podem automatizar tarefas como a importação de dados, limpeza do banco de dados, geração de relatórios, entre outras.
- Personalização: Você pode criar comandos que atendam às necessidades específicas da sua aplicação, tornando-a mais eficiente e adaptada ao seu contexto.
- Integração com sistemas externos: comandos customizados podem facilitar a integração da sua aplicação com sistemas externos, como APIs de terceiros.
- Facilidade de uso: ao criar comandos customizados, você pode simplificar processos complexos para os usuários da sua aplicação, permitindo que eles executem ações específicas com apenas um comando.
Curso Django - Fundamentos
Conhecer o cursoCriando comandos customizados no Django
Para criar um comando customizado no Django precisamos criar um arquivo com o nome do comando desejado dentro do diretório management/commands
dentro de alguma app do projeto.
meu_app/
├── management/
│ └── commands/
│ └── nome_do_comando.py
Vamos criar um comando que lista todos os usuários cadastros no sistema, esse comando irá se chamar listusers
, logo, precisamos criar um arquivo chamado listusers.py
.
Dentro do arquivo que implementa o nosso comando precisamos criar uma classe chamada Command
que herda da classe BaseCommand
do módulo django.core.management.base
.
Essa classe precisa então implementar o método handle
onde iremos escrever o código necessário para a correta execução do comando.
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "Lista todos os usuários do sistema"
def handle(self, *args, **options):
users = User.objects.all()
if len(users) <= 0:
self.stdout.write("Nenhum usuário registrado no sistema")
return
for user in users:
self.stdout.write(
f"{user.username} - {user.email}"
)
Um ponto importante de ser observado é que não utilizamos a função print
para exibir informações no console e sim o método self.stdout.write
, ao escrever comandos customizados para o Django essa é a forma correta de exibir informações no console, além disso, também temos o método self.stderr.write
para quando queremos exibir alguma mensagem de erro no console durante a execução do nosso comando.
Agora, podemos testar o nosso comando executando python manage.py listusers
no terminal, importante frisar que a sua app precisa estar listada na constante INSTALLED_APPS
do arquivo settings.py
.
Curso Django - Banco de dados com Django ORM - Parte 2
Conhecer o cursoAceitando argumentos no comando
Os nossos comandos também podem receber argumentos durante a sua execução, para isso, precisamos implementar o método add_arguments
onde iremos definir quais os argumentos o nosso argumento suporta receber.
Vamos alterar a nossa implementação para permitir que o nosso comando listusers
possa receber um argumento opcional chamado --filter
que permitirá filtramos os resultados da busca de usuário com base no username
ou no email
.
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "Lista todos os usuários do sistema"
def add_arguments(self, parser):
parser.add_argument(
"--filter",
type=str,
required=False,
help="Filtrar usuários por username ou email",
)
def handle(self, *args, **options):
filter = options.get("filter")
users = User.objects.all()
if filter:
users = users.filter(username__icontains=filter) | users.filter(
email__icontains=filter
)
if len(users) <= 0:
self.stdout.write("Nenhum usuário foi encontrado")
return
for user in users:
self.stdout.write(f"{user.username} - {user.email}")
Veja que no método add_arguments
utilizamos parser.add_argument
para registar um novo argumento para o nosso comando, nesse momento podemos informar se o argumento é obrigatório, se ele terá um valor padrão, uma mensagem explicando o proposito desse argumento, qual o seu tipo e muitas outras opções.
Uma vez que os argumentos tenham sido registrado, podemos fazer uso deles na lógica do nosso comando no método handle
, e para termos acesso aos valores passados através desses argumentos basta utilizar options['nome_argumento']
.
Agora podemos executar comando da seguinte maneira: python manage.py listusers --filter cleyson
. Dessa forma, somente os usuários que possuam “cleyson” no username ou no email serão listados.
Curso Django - Módulo administrativo Django Admin
Conhecer o cursoTestando comandos customizados no Django
Comandos customizados no Django podem ser testando utilizando a função call_method
para podermos executar um determinado comando via código e a saída do comando pode ser redirecionada para uma instância da classe StringIO
.
No arquivo tests.py
da nossa app iremos colocar o seguinte código:
from io import StringIO
from django.test import TestCase
from django.core.management import call_command
from django.contrib.auth.models import User
class ListUsersTest(TestCase):
def setUp(self):
User.objects.create_user(
username="user1", email="user1@mail.com", password="123"
)
User.objects.create_user(
username="user2", email="user2@mail.com", password="123"
)
def test_list_users(self):
out = StringIO()
call_command("listusers", stdout=out)
self.assertIn("user1 - user1@mail.com", out.getvalue())
self.assertIn("user2 - user2@mail.com", out.getvalue())
def test_list_users_with_filter(self):
out = StringIO()
call_command("listusers", "--filter=user1", stdout=out)
self.assertIn("user1 - user1@mail.com", out.getvalue())
self.assertNotIn("user2 - user2@mail.com", out.getvalue())
Veja que no método setUp
da nossa classe de teste fizemos a criação de dois usuários para termos dados de teste e dentro do método de teste utilizamos a função call_method
para realizar a execução do nosso comando e através do parâmetro stdout
informamos para onde será feito o redirecionamento da saída do nosso comando. Assim podemos verificar a saída do nosso comando e assim assegurar que o seu funcionamento ocorreu como esperado.
Conclusão
Em resumo, a criação de comandos customizados no Django oferece aos desenvolvedores uma ferramenta poderosa para automatizar tarefas, personalizar funcionalidades e integrar sistemas externos de forma eficiente. Ao entender os benefícios e seguir os passos para criar e testar esses comandos, você pode melhorar significativamente a experiência de desenvolvimento e a funcionalidade das suas aplicações Django. Ao dominar essa habilidade, você estará mais preparado para enfrentar desafios complexos e criar soluções sob medida para suas necessidades específicas. Experimente criar seus próprios comandos customizados e veja como eles podem impulsionar a eficiência e flexibilidade do seu desenvolvimento no Django.
Caso queira aprender mais sobre o Django, saiba que aqui na TreinaWeb nós temos a formação Especialista Django que possui 47h05 de vídeos e um total de 114 exercícios.
Veja alguns dos os cursos que fazem parte desta formação:
- Django - Fundamentos
- Django - Banco de dados com Django ORM
- Django - Mapeando de banco de dados legado
- Django - Trabalhando com validações
- Django - Autenticação e Autorização
- Django - Trabalhando com class-based views
- Django - Módulo administrativo Django Admin
- Django - Sistema de gerenciamento de clínicas PET
- Docker - Configurando um ambiente Python e Django
- Django - Instalação do ambiente de produção e deploy em uma VPS
- Django - Desenvolvimento de APIs REST
- Django - Autenticação e Autorização com JWT
- Django - API de gerenciamento de professores e aulas particulares
- Django e OpenAI - Entrevistador usando a inteligência artificial GPT