Reputation: 8635
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.
Upvotes: 17
Views: 6805
Reputation: 309
You can monkey-patch the default admin site like so:
Top level urls.py
:
from django.contrib import admin
from django.urls import include, path
...
# Store a reference to the default each_context so we don't cause an infinite loop when we override it.
base_admin_context = admin.site.each_context
def custom_admin_context(request):
context = base_admin_context(request)
# Do anything we want with the context
# Example: adding a custom sidebar nav section at the top
context["available_apps"].insert(
0,
{
"name": "Extra stuff",
"app_url": "/admin/extra/",
"has_module_perms": True,
"models": [
{
"object_name": None,
"name": "A custom admin dashboard",
"admin_url": "/admin/extra/dashboard",
}
],
},
)
return context
admin.site.each_context = custom_admin_context
...
urlpatterns = [...]
If you are already overriding other default admin.site values, this can be a low-complexity solution.
Upvotes: 0
Reputation: 12903
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.
Upvotes: 5
Reputation: 8635
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.
Upvotes: 9