Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@titusz
Last active February 12, 2016 12:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save titusz/dfc20bc6fc40ff82a286 to your computer and use it in GitHub Desktop.
Save titusz/dfc20bc6fc40ff82a286 to your computer and use it in GitHub Desktop.
Monkeypatch for Django Suit to support separate SUIT_CONFIGs for multiple Admin Sites
def suit_multi_admin():
"""Monkeypatch Django Suit to support multiple Admin Sites
Usage:
put this code for example in myapp/monkey.py
Activate the monkeypatch in your models.py:
from monkey import suit_multi_admin
suit_multi_admin()
Put a separate configuration in your settings as:
SUIT_CONFIG_<MYADMIN> = {...}
where MYADMIN is the upper case name of your custom AdminSite.name
"""
import suit.config
from suit.templatetags import suit_menu
from django.conf import settings
from django.core.handlers.wsgi import WSGIRequest
def get_config(param=None, config_key='SUIT_CONFIG'):
"""
Accept a custom config_key kwarg
"""
if hasattr(settings, config_key):
config = getattr(settings, config_key, {})
else:
config = suit.config.default_config()
if param:
value = config.get(param)
if value is None:
value = suit.config.default_config().get(param)
return value
return config
suit.config.get_config = get_config
@suit_menu.register.assignment_tag(takes_context=True)
def get_menu(context, request):
"""
Pass admin_site_name go Menue via context
"""
if not isinstance(request, WSGIRequest):
return None
# Try to get app list
admin_site = suit_menu.get_admin_site(context.current_app)
template_response = admin_site.index(request)
context['admin_site_name'] = admin_site.name
try:
app_list = template_response.context_data['app_list']
except Exception:
return
return suit_menu.Menu(context, request, app_list).get_app_list()
suit_menu.get_menu = get_menu
def patched_init(self, context, request, app_list):
"""
Get admin_site_name from context
"""
self.request = request
self.app_list = app_list
self.admin_site_name = context.get('admin_site_name')
# Detect current app, if any
try:
self.ctx_app = context['app_label'].lower()
except Exception:
self.ctx_app = None
# Get current model plural name, if any
try:
self.ctx_model_plural = context['opts'].verbose_name_plural.lower()
except Exception:
self.ctx_model_plural = None
# Flatten all models from native apps
self.all_models = [model for app in app_list for model in app['models']]
# Init config variables
self.init_config()
super(suit_menu.Menu, self).__init__()
suit_menu.Menu.__init__ = patched_init
def patched_init_config(self):
"""
Set config_key based on admin_site_name.
"""
if self.admin_site_name and self.admin_site_name != 'admin':
config_key = 'SUIT_CONFIG_{}'.format(self.admin_site_name.upper())
else:
config_key = 'SUIT_CONFIG'
self.conf_exclude = get_config('MENU_EXCLUDE', config_key)
self.conf_open_first_child = get_config('MENU_OPEN_FIRST_CHILD', config_key)
self.conf_icons = get_config('MENU_ICONS', config_key)
self.conf_menu_order = get_config('MENU_ORDER', config_key)
self.conf_menu = get_config('MENU', config_key)
suit_menu.Menu.init_config = patched_init_config
@javivicente
Copy link

Hi!

Thank you for sharing your solution. This is a great patch indeed.

I´ve been trying to make it work in my project but the context.current_app (line 49) always returned None to me instead of my custom AdminSite name. In the end, I changed line 49 to grab the AdminSite name from the request and everything worked like a charm:

admin_site_name = request.path.split('-')[0].split('/')[1]
admin_site = suit_menu.get_admin_site(admin_site_name)

Please, notice that admin_site_name = request.path.split('-')[0].split('/')[1] assumes that your custom admin url has the pattern 'mycustom-admin'. In this example, the AdminSite name would be 'mycustom'. This is what Django requires to properly work with more than one admin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment