JavaScript¶
task-poll.js é auto-contido (sem dependências externas, sem jQuery) e
mora em django_celery_task_monitor/static/django_celery_task_monitor/js/task-poll.js.
Auto-inicialização¶
Assim que o script carrega, ele varre a página por elementos com o atributo
data-poll-url (exatamente o que task_status_badge.html e
task_status_panel.html renderizam) e começa a sondar cada um
automaticamente. Isso é o que faz a coluna do changelist e o painel do
change form “simplesmente funcionarem” quando você usa
CeleryTaskMonitorMixin — nenhum <script> de inicialização manual é
necessário.
Badge vs. painel¶
O mesmo task-poll.js atualiza os dois tipos de elemento, diferenciados
pela estrutura interna:
Badge (
task_status_badge.html): tem um.task-status-badge__label— recebe só o rótulo curto (status_display, ex.: “Concluída”).Painel (
task_status_panel.html): tem um.task-status-panel__message— recebe a frase completa, recomposta a cada poll e a cada segundo no cliente (para o relógio de “há X tempo” andar sem esperar o próximo poll). Fora isso, ambos compartilham a mesma lógica de dedupe, cleanup e troca de classe CSS por status.
API pública (window.TaskPoll)¶
TaskPoll.init(selector, options)¶
Inicia o polling de todos os elementos que casam com selector.
<script src="{% static 'django_celery_task_monitor/js/task-poll.js' %}"></script>
<script>
TaskPoll.init(".task-badge", {
pollInterval: 5000,
endpoint: "/admin/task-status/", // opcional se o elemento já tem data-poll-url
onUpdate: function (data, el) { /* a cada resposta recebida */ },
onSuccess: function (data, el) { console.log("Task concluída!", data); },
onError: function (data, el) { console.warn("Task falhou", data); },
});
</script>
Opções:
Opção |
Descrição |
|---|---|
|
URL de polling comum a todos os elementos (ignorada se o elemento já tiver |
|
Intervalo em ms (default: 5000). |
|
Chamado a cada resposta recebida do endpoint. |
|
Chamado quando a tarefa termina com |
|
Chamado quando a tarefa falha, é revogada, ou o |
|
Sobrescreve os textos padrão (pt-BR) usados nos painéis para esta chamada — ver abaixo. |
TaskPoll.stop(el)¶
Para o polling de um elemento específico e limpa o setInterval
correspondente.
TaskPoll.stopAll()¶
Para o polling de todos os elementos atualmente monitorados.
TaskPoll.configure(options)¶
Sobrescreve os textos padrão globalmente, para todas as chamadas de
init() feitas depois (incluindo a auto-inicialização):
<script src="{% static 'django_celery_task_monitor/js/task-poll.js' %}"></script>
<script>
TaskPoll.configure({
messages: {
queued: "Waiting to start.",
running: "Running for {time}.",
progress: "{percent}% complete.",
success: "Finished successfully.",
failure: "Finished with an error.",
revoked: "Cancelled.",
none: "No task in progress.",
},
});
</script>
Chame TaskPoll.configure() antes do DOMContentLoaded disparar
(ex.: logo depois do <script src="task-poll.js">, no <head>) para
que a auto-inicialização já use os textos customizados. As chaves
disponíveis são exatamente as do exemplo acima; {time} e {percent}
são substituídos literalmente (não são expressões).
Note que isso só afeta o texto renderizado no cliente — o texto usado
no primeiro render do servidor (antes do JavaScript rodar) e no campo
message do payload JSON vêm de models.py e usam o mecanismo normal
de i18n do Django (gettext), independentemente disso. Veja
Uso Avançado para como as duas fontes se relacionam.
Prevenção de duplicação e memory leaks¶
Cada elemento monitorado recebe o atributo
data-task-poll-active, que serve como guarda contra polling duplicado mesmo que o script seja avaliado mais de uma vez na mesma página (por exemplo, HTML re-inserido via AJAX).Um
MutationObserverobserva remoções no DOM e limpa automaticamente osetIntervalde qualquer badge removido da página, evitando memory leaks em SPAs ou changelists recarregados dinamicamente.O polling de um elemento para sozinho assim que a tarefa atinge um estado final (
SUCCESS,FAILUREouREVOKED— verdata.is_finishedno payload JSON).
Formato do payload JSON¶
Cada resposta do endpoint de polling (via mixin ou TaskStatusView) tem o
formato:
{
"task_id": "9c4b7a0a-...",
"task_name": "example_app.processar_relatorio",
"status": "PROGRESS",
"status_display": "Em processamento",
"message": "Tarefa em processamento há 12s. Processamento em 50%.",
"is_finished": false,
"created_at": "2026-08-21T12:47:30.779935+00:00",
"updated_at": "2026-08-21T12:47:35.299003+00:00",
"started_at": "2026-08-21T12:47:31.100000+00:00",
"progress": {"percent": 50}
}
message: frase pronta (mesmo texto que o painel mostra), útil para qualquer consumidor do endpoint que não usetask-poll.js.started_at: quando a execução realmente começou, segundoTaskResult.date_started—nullse o Celery ainda não registrou isso (requerCELERY_TASK_TRACK_STARTED = Trueno projeto host, ver Configuração).task-poll.jsusa este campo para calcular o tempo decorrido no relógio local.progress: odictdecodificado de um estado customizado (ex.PROGRESS), ounullpara estados padrão do Celery — ver Uso Avançado.
Quando status é FAILURE, um campo error adicional aparece, com
{"message": ..., "traceback": ...} — traceback só vem preenchido
para quem tem a permissão view_task_trace (ver Permissões).