Extras

Signals

Signals são uma forma de executar automaticamente um código em resposta a determinados eventos que ocorrem no sistema, como: Quando um modelo é salvo (post_save), quando um modelo é deletado (post_delete), quando um usuário faz login ou logout, entre outros eventos. Permitem desacoplar lógica do fluxo principal da aplicação. Assim, você não precisa colocar regras extras diretamente no save() do modelo, por exemplo.
Em termos simples, um Signal no Django é como um gatilho (trigger) que executa um bloco de código sempre que um evento específico acontece. Pode disparar antes ou depois de uma operação (pre_save, post_save). Funciona tanto para operações de banco quanto para eventos do ciclo de vida da aplicação.

Pode criar um arquivo chamado singnals.py dentro do seu app. Mas o Django não executa automaticamente o signals.py só por existir. Para que seus signals sejam registrados e ouvidos, você precisa garantir que o arquivo seja importado quando o Django inicializa. Quando o Django roda ele carrega os apps registrados em INSTALLED_APPS. Dentro de cada app, existe o arquivo apps.py que define uma classe AppConfig, o Django executa o método ready() da sua classe AppConfig. É neste método que você deve importar o arquivo signals.py.


Tabela com os principais Sinais:
Signal Descrição Quando é Chamado Importação
pre_save Antes de um modelo ser salvo no banco de dados Antes do método save() ser executado django.db.models.signals
post_save Após um modelo ser salvo no banco de dados Depois do save() concluir django.db.models.signals
pre_delete Antes de um objeto ser deletado Antes do método delete() ser chamado django.db.models.signals
post_delete Após um objeto ser deletado Depois que o objeto foi removido do banco django.db.models.signals
m2m_changed Quando uma relação ManyToMany é alterada Sempre que .add(), .remove() ou .clear() django.db.models.signals
pre_migrate Antes de rodar o comando migrate Antes de aplicar qualquer migration django.db.models.signals
post_migrate Após rodar o comando migrate Após todas as migrations serem aplicadas django.db.models.signals
class_prepared Quando um modelo é totalmente carregado pela metaclass do Django Quando o Django finaliza a preparação de um modelo django.db.models.signals
request_started Quando o Django começa a processar uma nova requisição HTTP Ao início de cada request django.core.signals
request_finished Quando o Django termina de processar uma requisição HTTP Ao final de cada request django.core.signals
got_request_exception Quando uma exceção ocorre durante o processamento de uma requisição Quando ocorre uma exception no ciclo de request django.core.signals
connection_created Quando uma conexão com o banco de dados é criada Ao abrir uma nova conexão com o DB django.db.backends.signals
signals.py
# Importa o signal post_save, que é disparado após um modelo ser salvo
from django.db.models.signals import post_save

# Importa o decorador receiver, que registra a função como ouvinte de um signal
from django.dispatch import receiver

# Importa o modelo User padrão do Django
from django.contrib.auth.models import User

# Importa o modelo Perfil que está associado ao User
from .models import Perfil


# O decorador @receiver conecta a função abaixo ao signal post_save do modelo User
@receiver(post_save, sender=User)
def criar_perfil_automatico(sender, instance, created, **kwargs):
    # A função será executada sempre que um User for salvo
    # 'created' é True se o User acabou de ser criado
    print("Objeto salvo:", instance)
    print("Foi criado?", created)
    if created:
        # Cria um Perfil associado ao User recém-criado
        Perfil.objects.create(user=instance)

O código serve para garantir que todo User criado tenha um Perfil correspondente automaticamente, sem depender de chamadas manuais. Sempre que um novo usuário (User) for criado, o Django automaticamente: Dispara o signal post_save, executa a função criar_perfil_automatico, cria um perfil associado a esse usuário.

  • Signal (post_save): Evento disparado após um objeto ser salvo no banco.
  • Receiver (@receiver): Decorador que registra a função para "ouvir" o signal indicado.
  • sender=User: Limita o signal para ser ativado apenas quando um User for salvo.
  • instance: É o próprio objeto User que acabou de ser salvo.
  • created: Indica se o objeto foi recém-criado (True) ou apenas atualizado (False).

apps.py
from django.apps import AppConfig

class SeuAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'seu_app'

    def ready(self):
        import seu_app.signals  # importa o arquivo signals.py e registra os signals

# OBS -EM __init__.py Certifique-se de que o Django use seu AppConfig:
default_app_config = 'seu_app.apps.SeuAppConfig'

Django Cleanup

O pacote externo django-cleanup confiável e robusto, ele cuida de qualquer FileField e ImageField do seu projeto automaticamente. Remove os arquivos quando um objeto é deletado ou quando o arquivo é substituído, sem precisar programar manualmente. Evita o risco de esquecer de implementar isso em um save() ou signal específico. Basta instalar com o pip e adicionar ao settings.py:
INSTALLED_APPS = [
# ...
    'django_cleanup.apps.CleanupConfig',
]