Last active
February 12, 2016 12:41
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.