Add a custom button to a Django application's admin page

Viewed 45717

I have an application in Django with a routine which would be available only to the admin. What I want to do is add a button to perform the routine in this application's section of the admin app.

Am I supposed to make a template for it, and if that's the case, how do I add a html template for an app in the admin. Or maybe there's a command to simply add a button?

5 Answers

Django1.10:

1) Override admin/submit_line.html:

{% load i18n admin_urls %}
<div class="submit-row">
{% if extra_buttons %}
    {% for button in extra_buttons %}
        {{ button }}
    {% endfor %}
{% endif %}
{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" />{% endif %}
{% if show_delete_link %}
    {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %}
    <p class="deletelink-box"><a href="{% add_preserved_filters delete_url %}" class="deletelink">{% trans "Delete" %}</a></p>
{% endif %}
{% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" />{% endif %}
{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}
{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" />{% endif %}
</div>

This assumes, of course, that button's string representation is an appropriate browser input or button element, and is marked safe with django.utils.safestring.mark_safe. Alternatively, you could use the safe template filter or access the attributes of button directly to construct the <input>. In my opinion, it's better to isolate such things to the python level.

2) Override MyModelAdmin.change_view:

def change_view(self, request, object_id, form_url='', extra_context=None):
    extra_context = extra_context or self.extra_context()
    return super(PollAdmin, self).change_view(
        request, object_id, form_url, extra_context=extra_context,
    )

This method enables you to add buttons to any ModelAdmin easily. Alternatively to step (1), you could extend admin/change_form.html and override block submit_row. This would be slightly more verbose due to extra tags required in the template.

If you want the extra action available across all of your models (or a specific subset) then subclass ModelAdmin with the desired functionality (an example would be to add archiving to your models. You could even add an override for delete--and the other default buttons--so that the mode is archived instead of deleted; this would require some template modifications)

You might consider adding a custom admin action for this kind of object (similar to the built in 'delete'), if appropriate. Some benefits include: "pure Django", not having to mess with templates, and being able to act on multiple objects at once.

Django’s admin lets you write and register “actions” – simple functions that get called with a list of objects selected on the change list page. If you look at any change list in the admin, you’ll see this feature in action; Django ships with a “delete selected objects” action available to all models.

https://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/

I got the idea from this article on how to add a custom action button, which is another answer all together. I was able to get by with the simpler built-in actions though.

https://medium.com/@hakibenita/how-to-add-custom-action-buttons-to-django-admin-8d266f5b0d41

Related