Additional save button on Django admin pages with extra functionality

How can you add an additional Save-button on admin list view pages, like shown on the image, that saves the changes but also does something extra before or afterwards? In my case, I need to export the changes to an external database.

I know that it possible to achieve this functionality via “actions” but it is cumbersome to select the correct action from select-box, when you need to do it repetitively over and over again.

It would be beneficial to be able to add extra save button both to the list view and the change view.

Probably the easiest way to do this would be to override the template(s) you wish to change.

See Overriding admin templates.

Add the button in those templates directing the submission to your view to perform your “something extra”, then redirecting you back to the appropriate admin page. (Probably either the list or edit page, whichever is appropriate for you.)

1 Like

Here is how I did this. The solution is as ugly as hell. I wish there was easier and more elegant way to do this. In my opinion, there should be a feature in ModelAdmin for having an extra save-button like this.

(This only works in list view)

You need to overwrite the pagination.html admin template:

{% 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>

Then add code like this to your admin.ModelAdmin class:

    # ------------------
    # 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."
export"
    # ------------------

    _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
    # ------------------