Django: How to add a custom button to admin change form page that executes an admin action?
<p>I have already defined a custom admin action for my model which works perfectly as expected. I also looked at multiple ways of adding a button to the admin change form page here on SO. The only step that I am missing is how do I make a button in the change form page execute my custom admin action with current object?</p>
<p>The goal is to allow admin to inspect every object individually and perform an action on them without needing to go back to list view, selecting the inspected object, and executing the action from the list.</p>
<p>My custom admin action looks like this:</p>
<pre class="lang-py prettyprint-override"><code>def admin_apply_change(modeladmin, request, queryset):
    # loop over objects in query set and perform action
</code></pre>
<p>I am assuming there is a simple and clean way of calling this action in admin change form, where the <code>queryset</code> would only contain the currently opened object the admin is looking at.</p>
<p><strong>NOTE:</strong> It would be preferable if the button is at the bottom of the change form, next to <code>Save</code> button instead of being at top with <code>History</code> which is not very visible.</p>
<h1>Solution</h1>
<p><a href="https://stackoverflow.com/a/34899874/28360">See the answer below</a> by <a href="https://stackoverflow.com/users/1288767/remi">Remi</a> for the solution. In order to make it work the following corrections are needed:</p>
<ol>
<li><p>In the override of <code>response_change</code> initialization of some variables is missing:</p>
<pre class="lang-py prettyprint-override"><code>opts = self.model._meta
pk_value = obj._get_pk_val()
preserved_filters = self.get_preserved_filters(request)
</code></pre>
</li>
<li><p>New inclusion tag <code>custom_submit_row</code> should be placed in templatetags and not in admin (see <a href="https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/" rel="nofollow noreferrer">docs for custom templatetags</a>)</p>
</li>
<li><p>This is the oversight you could lose some time on. In <code>change_form.html</code> you not only have to change the suggested line:</p>
<pre><code>{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
</code></pre>
<p>but also the more important line at the bottom where <code>submit_row</code> appears:</p>
<pre><code>{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
</code></pre>
<p><em>It is located just above the javascript block in <code>change_form.html</code>.</em></p>
</li>
</ol>