Personalizaciones en JavaScript del admin

Eventos de formulario inline

Puede que desee ejecutar algún código JavaScript cuando se agregue o elimine un formulario inline en la forma de cambio del admin. Los eventos formset:added y formset:removed permiten esto. event.detail.formsetName es el nombre del conjunto de formularios al que pertenece la fila. Para el evento formset:added, event.target es la fila recién agregada.

En su plantilla personalizada change_form.html, extiende el bloque admin_change_form_document_ready y agrega el código del escuchador de eventos:

{% extends 'admin/change_form.html' %}
{% load static %}

{% block admin_change_form_document_ready %}
{{ block.super }}
<script src="{% static 'app/formset_handlers.js' %}"></script>
{% endblock %}
app/static/app/formset_handlers.js
document.addEventListener('formset:added', (event) => {
    if (event.detail.formsetName == 'author_set') {
        // Do something
    }
});
document.addEventListener('formset:removed', (event) => {
    // Row removed
});

Dos puntos a tener en cuenta:

  • El código JavaScript debe ir en un bloque de plantilla si está heredando admin/change_form.html o no se renderizará en el HTML final.

  • Se agrega {{ block.super }} porque el bloque admin_change_form_document_ready de Django contiene código JavaScript para manejar varias operaciones en la forma de cambio y necesitamos que se renderice también.

Compatibilidad con versiones de Django anteriores a 4.1

Si tu escucha de eventos todavía tiene que soportar versiones antiguas de Django, debes utilizar jQuery para registrar tu escucha de eventos. jQuery maneja eventos JavaScript pero lo contrario no es cierto.

Podrías comprobar la presencia de event.detail.formsetName y caer en el viejo formato de la firma del escucha como sigue:

function handleFormsetAdded(row, formsetName) {
    // Do something
}

$(document).on('formset:added', (event, $row, formsetName) => {
    if (event.detail && event.detail.formsetName) {
        // Django >= 4.1
        handleFormsetAdded(event.target, event.detail.formsetName)
    } else {
        // Django < 4.1, use $row and formsetName
        handleFormsetAdded($row.get(0), formsetName)
    }
})