管理的 JavaScript 自定义

内联表单事件

You may want to execute some JavaScript when an inline form is added or removed in the admin change form. The formset:added and formset:removed events allow this. event.detail.formsetName is the formset the row belongs to. For the formset:added event, event.target is the newly added row.

Changed in Django 4.1:

In older versions, the event was a jQuery event with $row and formsetName parameters. It is now a JavaScript CustomEvent with parameters set in event.detail.

在你的自定义 change_form.html 模板中,扩展 admin_change_form_document_ready 块并添加事件监听器代码:

  1. {% extends 'admin/change_form.html' %}
  2. {% load static %}
  3. {% block admin_change_form_document_ready %}
  4. {{ block.super }}
  5. <script src="{% static 'app/formset_handlers.js' %}"></script>
  6. {% endblock %}

app/static/app/formset_handlers.js

  1. document.addEventListener('formset:added', (event) => {
  2. if (event.detail.formsetName == 'author_set') {
  3. // Do something
  4. }
  5. });
  6. document.addEventListener('formset:removed', (event) => {
  7. // Row removed
  8. });

有两点需要注意:

  • 如果你继承了 admin/change_form.html,JavaScript 代码必须放在模板块中,否则它不会在最终的 HTML 中呈现。
  • 添加 {{ block.super }} 是因为 Django 的 admin_change_form_document_ready 块中包含了 JavaScript 代码,用于处理更改表单中的各种操作,而我们也需要渲染这些代码。

Supporting versions of Django older than 4.1

If your event listener still has to support older versions of Django you have to use jQuery to register your event listener. jQuery handles JavaScript events but the reverse isn’t true.

You could check for the presence of event.detail.formsetName and fall back to the old listener signature as follows:

  1. function handleFormsetAdded(row, formsetName) {
  2. // Do something
  3. }
  4. $(document).on('formset:added', (event, $row, formsetName) => {
  5. if (event.detail && event.detail.formsetName) {
  6. // Django >= 4.1
  7. handleFormsetAdded(event.target, event.detail.formsetName)
  8. } else {
  9. // Django < 4.1, use $row and formsetName
  10. handleFormsetAdded($row.get(0), formsetName)
  11. }
  12. })