16

How do I add extra context to all admin webpages?

I use default Django Admin for my admin part of a site.

Here is an url entry for admin:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

And my apps register their standard view models using:

admin.site.register(Tag, TagAdmin)

My problem, is that I want to display an extra field in admin template header bar and I have no idea how to add this extra context.

My first bet was adding it in url patterns like below:

urlpatterns = [
    url(r'^admin/', admin.site.urls, {'mycontext': '123'}),
]

But that gives an error:

TypeError at /admin/tickets/event/4/change/

change_view() got an unexpected keyword argument 'mycontext'

Can you give any suggestion? I really do not want to modify every AdminModel class I have to insert this context, as I need it on every admin page.

Thanks.

alandarev
  • 8,349
  • 2
  • 34
  • 43
  • 1
    OP's self-answer did not work for me, possibly because I needed to access the extra data on the admin's `index.html` page -- this is what did work (however superfluous it may be) https://stackoverflow.com/a/40265975/6158303 – kt-0 Aug 14 '19 at 16:09

2 Answers2

9

Found the solution, url registration has to be:

urlpatterns = [
    url(r'^admin/', admin.site.urls, {'extra_context': {'mycontext': '123'}}),
]

Its a context dictionary inside of a dictionary with 'extra_context' as a key.

alandarev
  • 8,349
  • 2
  • 34
  • 43
  • do you know what view this would get added in, if say I wanted to add a specific queryset? – kt-0 Aug 14 '19 at 12:01
  • After taking your advice (which fixed the problem I was trying to solve very well!) I found that the "change password" form in the Django Admin was broken. This seems like it may be a bug in Django. To get both the extra context and the change password form I had to use Django's ModelAdmin 'add_view' and 'change_view' methods on the individual forms after all. https://stackoverflow.com/a/64072756/706797 – Ryan Sep 26 '20 at 00:28
4

Another technique, more complex but allows different context per request (probably unavailable at OP time):

my_project/admin.py (create if missing)

from django.contrib import admin
from django.contrib.admin.apps import AdminConfig


class MyAdminConfig(AdminConfig):
    default_site = 'my_project.admin.MyAdminSite'


class MyAdminSite(admin.AdminSite):
    def each_context(self, request):
        context = super().each_context(request)
        context.update({
            "whatever": "this is",
            "just a": "dict",
        })
        return context

settings.py

INSTALLED_APPS = [
    ...
    'my_project.admin.MyAdminConfig',  # replaces 'django.contrib.admin'
    ...

The replace / extend admin class code is taken from the official docs except this is all in one file.

Javier Buzzi
  • 6,296
  • 36
  • 50
frnhr
  • 12,354
  • 9
  • 63
  • 90
  • ModuleNotFoundError: No module named 'my_project', when I add it in INSTALLED_APPS – Martin Taleski Apr 06 '21 at 11:15
  • @MartinTaleski That looks like a path issue. Be sure to use the directory that holds your `wsgi.py` instead of `my_project`, or create a new module inside the project root and use its name. BTW also thanks for the edit. Dumb me clicked "rollback" by accident, sorry. – frnhr Apr 06 '21 at 12:22