Often I find that I need to include administration views in my site, such as statistics, management, etc etc. When these are more than just model CRUD views, a good idea is to extend the builtin Django admin site, as it’s the easiest to do.

While looking at the docs, however, I realised they were a bit cryptic and lacked good examples. It didn’t take me long to figure out how to do it, but here’s some example code for people who might not want to waste time figuring it out:

from django.conf.urls import url
from django.contrib import admin
from django.http import HttpResponse

def my_view(request):
    return HttpResponse("Hello!")

def get_admin_urls(urls):
    def get_urls():
        my_urls = [
            url(r'^my_view/$', admin.site.admin_view(my_view))
        return my_urls + urls
    return get_urls

admin_urls = get_admin_urls(admin.site.get_urls())
admin.site.get_urls = admin_urls

As you can see, it’s a pretty straightforward piece of code. It’s one view and an extension to the patterns of admin.site. However, since we need to monkey-patch get_urls to another function that inherits from it, it is a bit tricky to do, so I just wrote a function that returns another one.

In this case, get_admin_urls accepts the current admin URL list and extends it, returning get_urls, a reference to the function (not a call), and replaces the original one.

If you visit /admin/my_view/ now, you should be greeted by a friendly “hello”!

EDIT: As mattmcc in #django told me, one can just subclass an AdminSite instance just as we do for a ModelAdmin instance and avoid all the monkeypatching. I second that, as it is a more elegant solution! Just keep in mind that you need to call the subclass instead of the original admin.site in your urlconf.