55from django .contrib .admin import AdminSite
66from django .http import HttpRequest
77from django .utils .translation import gettext_lazy as _
8+ from django .contrib .contenttypes .models import ContentType
89from adminlteui .templatetags .adminlte_options import get_adminlte_option
910from adminlteui .models import Menu
1011
@@ -30,7 +31,25 @@ def get_reverse_link(link):
3031 except Exception as e :
3132 return None
3233
33- def get_custom_menu (available_apps ):
34+
35+ def get_custom_menu (request ):
36+ """
37+ use content_type and user.permission control the menu
38+
39+ `label:model`
40+
41+ :param request:
42+ :return:
43+ """
44+ all_permissions = request .user .get_all_permissions ()
45+
46+ limit_for_internal_link = []
47+ for permission in all_permissions :
48+ app_label = permission .split ('.' )[0 ]
49+ model = permission .split ('.' )[1 ].split ('_' )[1 ]
50+ limit_for_internal_link .append ('{}:{}' .format (app_label , model ))
51+
52+ limit_for_internal_link = set (limit_for_internal_link )
3453 new_available_apps = []
3554 menu = Menu .dump_bulk ()
3655 for menu_item in menu :
@@ -42,28 +61,41 @@ def get_custom_menu(available_apps):
4261 new_available_apps_item ['name' ] = data .get ('name' )
4362 new_available_apps_item ['icon' ] = data .get ('icon' )
4463
45- if data .get ('link_type' ) in (0 , 1 ):
46- new_available_apps_item ['admin_url' ] = get_reverse_link (
47- data .get ('link' ))
48-
49- children = (menu_item .get ('children' ))
64+ children = menu_item .get ('children' )
5065 if not children :
51- new_available_apps .append (new_available_apps_item )
66+ # skip menu_item that no children and link type is devide.
67+ if data .get ('link_type' ) in (0 , 1 ):
68+ new_available_apps_item ['admin_url' ] = get_reverse_link (
69+ data .get ('link' ))
70+ new_available_apps .append (new_available_apps_item )
5271 continue
5372 new_available_apps_item ['models' ] = []
5473
5574 for children_item in children :
75+ if children_item .get ('data' ).get ('link_type' ) == 0 :
76+ # internal link should connect a content_type, otherwise it will be hide.
77+ if children_item .get ('data' ).get ('content_type' ):
78+ obj = ContentType .objects .get (id = children_item .get ('data' ).get ('content_type' ))
79+ # if user hasn't permission, the model will be skip.
80+ if obj .app_label + ':' + obj .model not in limit_for_internal_link :
81+ continue
82+ else :
83+ continue
84+
5685 if children_item .get ('data' ).get ('valid' ) is False :
5786 continue
58- new_children_item = {}
87+ new_children_item = dict ()
5988 new_children_item ['name' ] = children_item .get ('data' ).get ('name' )
6089 new_children_item ['admin_url' ] = get_reverse_link (
6190 children_item .get ('data' ).get ('link' )
6291 )
92+ if not new_children_item ['admin_url' ]:
93+ continue
6394 new_children_item ['icon' ] = children_item .get ('data' ).get ('icon' )
6495 # new_children_item['admin_url'] = children_item.get('link')
6596 new_available_apps_item ['models' ].append (new_children_item )
66- new_available_apps .append (new_available_apps_item )
97+ if new_available_apps_item ['models' ]:
98+ new_available_apps .append (new_available_apps_item )
6799
68100 return new_available_apps
69101
@@ -75,6 +107,12 @@ def get_menu(context, request):
75107 """
76108 if not isinstance (request , HttpRequest ):
77109 return None
110+
111+ use_custom_menu = get_adminlte_option ('USE_CUSTOM_MENU' )
112+ if use_custom_menu .get ('USE_CUSTOM_MENU' ,
113+ '0' ) == '1' and use_custom_menu .get ('valid' ) is True :
114+ return get_custom_menu (request )
115+
78116 # Django 1.9+
79117 available_apps = context .get ('available_apps' )
80118 if not available_apps :
@@ -94,11 +132,6 @@ def get_menu(context, request):
94132 if not available_apps :
95133 logging .warn ('adminlteui was unable to retrieve apps list for menu.' )
96134
97- use_custom_menu = get_adminlte_option ('USE_CUSTOM_MENU' )
98- if use_custom_menu .get ('USE_CUSTOM_MENU' ,
99- '0' ) == '1' and use_custom_menu .get ('valid' ) is True :
100- return get_custom_menu (available_apps )
101-
102135 for app in available_apps :
103136 if app .get ('app_label' ) == 'django_admin_settings' :
104137 app .get ('models' ).insert (0 ,
0 commit comments