How to extend the Django admin site with custom views ¶
To include custom administration views in a Django site, you can extend the builtin Django admin site itself
file "backend/admin.py"
from django.contrib import admin from django.conf.urls import patterns from django.conf.urls import url from django.urls import path from django.shortcuts import get_object_or_404 from .admin_views import color_schema_view class ColorAdmin(admin.ModelAdmin): def get_urls(self): info = self.model._meta.app_label, self.model._meta.model_name urls = super(ColorAdmin, self).get_urls() my_urls = patterns('', # or: # path('<uuid:pk>/schema/', ... url(r'^(?P<object_id>.*)/schema/$', self.admin_site.admin_view(self.schema), {}, name="%s_%s_schema" % info), ) return my_urls + urls def schema(self, request, object_id): color = get_object_or_404(Color, id=int(object_id)) return color_schema_view(request, self, color)
file "backend/admin_views.py"
from django.shortcuts import render def color_schema_view(request, model_admin, object): ... model = model_admin.model opts = model._meta return render( request, 'admin/backend/color/schema.html', { 'opts': opts, 'has_change_permission': model_admin.has_change_permission(request, object), 'original': object, ... } )
file "backend/templates/admin/backend/color/change_form.html"
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools-items %}
{{ block.super }}
<li>
<a href="{% url 'admin:backend_color_schema' object_id %}"><i class="icon-tint icon-alpha75"></i>{% trans 'Test schemas' %}</a>
</li>
{% endblock %}
file "backend/templates/admin/backend/color/schema.html"
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block breadcrumbs %}
<ul class="breadcrumb">
...
...
<li>
{% if has_change_permission %}
<a href="{% url opts|admin_urlname:'changelist' %}">
{{ opts.verbose_name_plural|capfirst }}
</a>
{% else %}
{{ opts.verbose_name_plural|capfirst }}
{% endif %}
<span class="divider">»</span>
</li>
<li>
{% if has_change_permission %}
<a href="{% url opts|admin_urlname:'change' original.id %}">
{{ original }}
</a>
{% else %}
{{ original }}
{% endif %}
</li>
</ul>
{% endblock %}
{% block extrahead %}
{{ block.super }}
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$("#colors_lut_form select").on('change', function() {
$(this).parent().submit();
});
});
})(jQuery);
</script>
{% endblock %}
{% block content %}
<div id="content-main" class="inner-two-columns">
<h1>{{original}} color schemas</h1>
...
</div>
{% endblock content %}
Another more recent example
@admin.register(Pallet) class PalletAdmin(BaseModelAdmin): ... def get_urls(self): urls = super().get_urls() info = self.model._meta.app_label, self.model._meta.model_name my_urls = [ path('<uuid:object_id>/export-resi/', self.export_resi, name='%s_%s_export-resi' % info), ] return my_urls + urls def export_resi(self, request, object_id): obj = Pallet.objects.get(id=object_id) next = reverse('admin:backend_pallet_change', args=(obj.id, )) try: TODO: DO WHAT IS REQUIRED ... messages.info(request, '...') except Exception as e: messages.error(request, str(e)) if settings.DEBUG: messages.warning(request, traceback.format_exc()) response = HttpResponseRedirect(next) return response
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
<li>
{% url opts|admin_urlname:'export-resi' original.pk|admin_urlquote as tool_url %}
<a href="{% add_preserved_filters tool_url %}" class="toollink">Esporta Resi</a>
</li>
{{ block.super }}
{% endblock object-tools-items %}
See also
AdminSite.each_context(request)
https://docs.djangoproject.com/en/4.0/ref/contrib/admin/#django.contrib.admin.AdminSite.each_context
