Declarando seu próprio Signal
Às vezes é necessário requisitar uma informação ou permitir que gatilhos sejam adicionados a determinados comportamentos de sua aplicação. Os signals são recursos criados para permitir que isso seja possível.
O conceito de signal e dispatcher é o de vincular uma função a um signal, ou seja, a um gatilho pré-declarado que será chamado quando um evento ocorrer. O dispatcher é o pacote responsável por vincular uma função ao signal e por chamá-lo quando necessário. Uma grande vantagem de signals sobre outras formas de se fazer isso é que com signals é possível vincular quantas funções quiser a um mesmo signal, que eles serão chamados em ordem.
Siga os passos abaixo:
- Supondo que sua aplicação se chama "minha_app" que contenha as classes
"Produto" e "Categoria", crie um arquivo "app_signals.py" em sua aplicação e insira as linhas abaixo::
from django.dispatch import Signal obter_informacoes_adicionais_do_produto = Signal()
como o nome sugere, vamos criar um comportamento para requisitar informações adicionais de um determinado produto e permitir que várias funções para isso sejam chamadas em tal momento sem nenhum vínculo direto.
- Agora edite o arquivo "views.py" de sua aplicação, adicionando as seguintes
linhas::
from models import Produto from app_signals import obter_informacoes_adicionais_do_produto def produto(request, produto_id): produto = Produto.objects.get(id=produto_id) informacoes_adicionais = [] obter_informacoes_adicionais_do_produto.send( produto, informacoes_adicionais=informacoes_adicionais, request=request ) return render_to_response( 'minha_app/produto.html', locals(), )
esta view está preparada para carregar as informações adicionais numa lista que receberá essas informações através do signal.
- Crie agora um template na pasta de templates de sua aplicação, com o nome
"produto.html" (ou seja, "minha_app/templates/produto.html")::
<html> <body> {{ produto.descricao }} <ul> {% for info in informacoes_adicionais %} <li>{{ info }}</li> {% endfor %} </ul> </body> </html>
esse template irá listar as informações adicionais resgatadas através do signal.
- Agora vamos declarar uma função para vincular ao signal. Esta função pode
ser declarada em qualquer módulo que seja carregado no momento da inicialização do projeto. Vamos editar então o arquivo "models.py" para criá-la, adicionando as seguintes linhas::
from app_signals import obter_informacoes_adicionais_do_produto def informacoes(signal, sender, **kwargs): produto=sender kwargs['informacoes_adicionais'].append(produto.id) kwargs['informacoes_adicionais'].append('outra info') obter_informacoes_adicionais_do_produto.connect(informacoes)
esse codigo irá adicionar algumas linhas à lista de informações.
- Por fim, adicione a seguinte URL ao arquivo de "urls.py" do projeto::
url(r'^produtos/(?P<produto_id>\d+)/$', 'minha_app.views.produto'),
Pronto! Agora ao carregar essa página em seu navegador, será exibida uma lista com as informações adicionadas pela função vinculada ao signal.
Tire outras dúvidas em nosso CookBook em Português