Browse Source

Add custom menu apps & models visibility/sorting

Denis K 9 năm trước cách đây
mục cha
commit
3471fa580a
3 tập tin đã thay đổi với 102 bổ sung11 xóa
  1. 1 0
      jet/settings.py
  2. 40 2
      jet/templatetags/jet_tags.py
  3. 61 9
      jet/utils.py

+ 1 - 0
jet/settings.py

@@ -6,3 +6,4 @@ JET_THEMES = getattr(settings, 'JET_THEMES', [])
 
 # Side menu
 JET_SIDE_MENU_COMPACT = getattr(settings, 'JET_SIDE_MENU_COMPACT', False)
+JET_SIDE_MENU_CUSTOM_APPS = getattr(settings, 'JET_SIDE_MENU_CUSTOM_APPS', None)

+ 40 - 2
jet/templatetags/jet_tags.py

@@ -126,12 +126,48 @@ def format_deletable_object(deletable_object):
 
 @register.assignment_tag(takes_context=True)
 def get_menu(context):
-    app_list = get_app_list(context)
+    if settings.JET_SIDE_MENU_CUSTOM_APPS not in (None, False):
+        app_list = get_app_list(context, False)
+        app_dict = {}
+        models_dict = {}
+
+        for app in app_list:
+            app_label = app.get('app_label', app.get('name'))
+            app_dict[app_label] = app
+
+            for model in app['models']:
+                if app_label not in models_dict:
+                    models_dict[app_label] = {}
+
+                models_dict[app_label][model['object_name']] = model
+
+            app['models'] = []
+
+        app_list = []
+
+        for item in settings.JET_SIDE_MENU_CUSTOM_APPS:
+            app_label, models = item
+
+            if app_label in app_dict:
+                app = app_dict[app_label]
+
+                for model_label in models:
+                    if model_label == '__all__':
+                        app['models'] = models_dict[app_label].values()
+                        break
+                    elif model_label in models_dict[app_label]:
+                        model = models_dict[app_label][model_label]
+                        app['models'].append(model)
+
+                app_list.append(app)
+    else:
+        app_list = get_app_list(context)
 
     current_found = False
 
     pinned = PinnedApplication.objects.values_list('app_label', flat=True)
 
+    all_aps = []
     apps = []
     pinned_apps = []
 
@@ -152,7 +188,9 @@ def get_menu(context):
         else:
             apps.append(app)
 
-    return {'apps': apps, 'pinned_apps': pinned_apps, 'all_apps': lambda: apps + pinned_apps}
+        all_aps.append(app)
+
+    return {'apps': apps, 'pinned_apps': pinned_apps, 'all_apps': all_aps}
 
 
 @register.assignment_tag

+ 61 - 9
jet/utils.py

@@ -1,12 +1,14 @@
 import datetime
 import json
+from django.apps.registry import apps
 from django.core.serializers.json import DjangoJSONEncoder
 from django.http import HttpResponse
-from django.core.urlresolvers import reverse, resolve
+from django.core.urlresolvers import reverse, resolve, NoReverseMatch
 from django.contrib import admin
 from django.contrib.admin import AdminSite
 from django.utils.encoding import smart_text
-from jet import settings
+from django.utils.text import capfirst
+import six
 from django.contrib import messages
 from django.utils.encoding import force_text
 from django.utils.functional import Promise
@@ -33,13 +35,63 @@ class JsonResponse(HttpResponse):
         super(JsonResponse, self).__init__(content=data, **kwargs)
 
 
-def get_app_list(context):
-    template_response = get_admin_site(context.get('current_app', '')).index(context['request'])
-
-    try:
-        return template_response.context_data['app_list']
-    except Exception:
-        return None
+def get_app_list(context, order=True):
+    admin_site = get_admin_site(context.get('current_app', ''))
+    request = context['request']
+
+    app_dict = {}
+    for model, model_admin in admin_site._registry.items():
+        app_label = model._meta.app_label
+        has_module_perms = model_admin.has_module_permission(request)
+
+        if has_module_perms:
+            perms = model_admin.get_model_perms(request)
+
+            # Check whether user has any perm for this module.
+            # If so, add the module to the model_list.
+            if True in perms.values():
+                info = (app_label, model._meta.model_name)
+                model_dict = {
+                    'name': capfirst(model._meta.verbose_name_plural),
+                    'object_name': model._meta.object_name,
+                    'perms': perms,
+                }
+                if perms.get('change', False):
+                    try:
+                        model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=admin_site.name)
+                    except NoReverseMatch:
+                        pass
+                if perms.get('add', False):
+                    try:
+                        model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=admin_site.name)
+                    except NoReverseMatch:
+                        pass
+                if app_label in app_dict:
+                    app_dict[app_label]['models'].append(model_dict)
+                else:
+                    app_dict[app_label] = {
+                        'name': apps.get_app_config(app_label).verbose_name,
+                        'app_label': app_label,
+                        'app_url': reverse(
+                            'admin:app_list',
+                            kwargs={'app_label': app_label},
+                            current_app=admin_site.name,
+                        ),
+                        'has_module_perms': has_module_perms,
+                        'models': [model_dict],
+                    }
+
+    # Sort the apps alphabetically.
+    app_list = list(six.itervalues(app_dict))
+
+    if order:
+        app_list.sort(key=lambda x: x['name'].lower())
+
+        # Sort the models alphabetically within each app.
+        for app in app_list:
+            app['models'].sort(key=lambda x: x['name'])
+
+    return app_list
 
 
 def get_admin_site(current_app):