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