Дополнительная кнопка сохранения на страницах администратора Django

Как можно добавить дополнительную кнопку Save на страницах просмотра списка в админке, как показано на изображении, которая сохраняет изменения, но также делает что-то дополнительное до или после этого?

Я знаю, что можно достичь этой функциональности через "действия", но это громоздко - выбирать нужное действие из select-box, когда нужно делать это многократно.

Было бы полезно иметь возможность добавить дополнительную кнопку сохранения как в представление списка, так и в представление изменений.

Example af a list view page with an extra save button

Я немного покопался и пришел к решению, которое уродливо как ад. Я хотел бы иметь более простой и элегантный способ сделать это. На мой взгляд, в ModelAdmin должна быть функция для дополнительной кнопки, подобной этой.

(Это работает только в режиме просмотра списка)

Вам нужно переписать шаблон админки pagination.html и добавить дополнительную кнопку сохранения:

{% load admin_list %}
{% load i18n %}
<p class="paginator">
{% if pagination_required %}
{% for i in page_range %}
    {% paginator_number cl i %}
{% endfor %}
{% endif %}
{{ cl.result_count }} {% if cl.result_count == 1 %}{{ cl.opts.verbose_name }}{% else %}{{ cl.opts.verbose_name_plural }}{% endif %}
{% if show_all_url %}<a href="{{ show_all_url }}" class="showall">{% translate 'Show all' %}</a>{% endif %}
{% if cl.formset and cl.result_count %}
    <input type="submit" name="_save" class="default" value="{% translate 'Save' %}">
    <input type="submit" name="_save" class="default" value="{% translate 'Save & export' %}" style="margin-right: 1em">{% endif %}
</p>

Затем добавьте код следующего содержания в ваш класс admin.ModelAdmin:

    # ------------------
    # Ugly hack to be able to add extra "Save & export" button to list
    # To understand take a look at the source code, changelist_view() in options.py, look for the comment:
    #   "Handle POSTed bulk-edit data."
    # ------------------

    _places_to_be_exported = []

    def save_model(self, request, obj, form, change):
        super().save_model(request, obj, form, change)
        # needs to be the same text as on that extra save-button
        if form.data['_save'] == 'Save & export':
            self._places_to_be_exported_to_es.append(obj.id)

    def message_user(self, request, message, level=messages.INFO, extra_tags="", fail_silently=False):
        super().message_user(request, message, level, extra_tags, fail_silently)
        if self._places_to_be_exported_to_es:
            queryset = PlaceName.objects.filter(id__in=self._places_to_be_exported)
            self._places_to_be_exported = []
            self._do_what_ever_you_need_to_do(queryset)

    # ------------------
    # End of this ugly hack
    # ------------------
Вернуться на верх