123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- from importlib import import_module
- try:
- from django.core.urlresolvers import reverse
- except ImportError: # Django 1.11
- from django.urls import reverse
- from django.template.loader import render_to_string
- from jet.dashboard import modules
- from jet.dashboard.models import UserDashboardModule
- from django.utils.translation import ugettext_lazy as _
- from jet.ordered_set import OrderedSet
- from jet.utils import get_admin_site_name, context_to_dict
- try:
- from django.template.context_processors import csrf
- except ImportError:
- from django.core.context_processors import csrf
- class Dashboard(object):
- """
- Base dashboard class. All custom dashboards should inherit it.
- """
- #: Number of columns in which widgets can be placed
- columns = 2
- #: Dashboard Modules (widgets) that dashboard is filled with, when the user open it for the first time
- #:
- #: List of dashboard module **instances**
- children = None
- #: Dashboard Modules (widgets) that user can add to dashboard at any time
- # (not created when the user open dashboard for the first time)
- #:
- #: List of dashboard module **classes**
- available_children = None
- app_label = None
- context = None
- modules = None
- class Media:
- css = ()
- js = ()
- def __init__(self, context, **kwargs):
- for key in kwargs:
- if hasattr(self.__class__, key):
- setattr(self, key, kwargs[key])
- self.children = self.children or []
- self.available_children = self.available_children or []
- self.set_context(context)
- def set_context(self, context):
- self.context = context
- self.init_with_context(context)
- self.load_modules()
- def init_with_context(self, context):
- """
- Override this method to fill your custom **Dashboard** class with widgets.
- You should add your widgets to ``children`` and ``available_children`` attributes.
- Usage example:
- .. code-block:: python
- from django.utils.translation import ugettext_lazy as _
- from jet.dashboard import modules
- from jet.dashboard.dashboard import Dashboard, AppIndexDashboard
- class CustomIndexDashboard(Dashboard):
- columns = 3
- def init_with_context(self, context):
- self.available_children.append(modules.LinkList)
- self.children.append(modules.LinkList(
- _('Support'),
- children=[
- {
- 'title': _('Django documentation'),
- 'url': 'http://docs.djangoproject.com/',
- 'external': True,
- },
- {
- 'title': _('Django "django-users" mailing list'),
- 'url': 'http://groups.google.com/group/django-users',
- 'external': True,
- },
- {
- 'title': _('Django irc channel'),
- 'url': 'irc://irc.freenode.net/django',
- 'external': True,
- },
- ],
- column=0,
- order=0
- ))
- """
- pass
- def load_module(self, module_fullname):
- package, module_name = module_fullname.rsplit('.', 1)
- package = import_module(package)
- module = getattr(package, module_name)
- return module
- def create_initial_module_models(self, user):
- module_models = []
- i = 0
- for module in self.children:
- column = module.column if module.column is not None else i % self.columns
- order = module.order if module.order is not None else int(i / self.columns)
- module_models.append(UserDashboardModule.objects.create(
- title=module.title,
- app_label=self.app_label,
- user=user.pk,
- module=module.fullname(),
- column=column,
- order=order,
- settings=module.dump_settings(),
- children=module.dump_children()
- ))
- i += 1
- return module_models
- def load_modules(self):
- module_models = UserDashboardModule.objects.filter(
- app_label=self.app_label,
- user=self.context['request'].user.pk
- ).all()
- if len(module_models) == 0:
- module_models = self.create_initial_module_models(self.context['request'].user)
- loaded_modules = []
- for module_model in module_models:
- module_cls = module_model.load_module()
- if module_cls is not None:
- module = module_cls(model=module_model, context=self.context)
- loaded_modules.append(module)
- self.modules = loaded_modules
- def render(self):
- context = context_to_dict(self.context)
- context.update({
- 'columns': range(self.columns),
- 'modules': self.modules,
- 'app_label': self.app_label,
- })
- context.update(csrf(context['request']))
- return render_to_string('jet.dashboard/dashboard.html', context)
- def render_tools(self):
- context = context_to_dict(self.context)
- context.update({
- 'children': self.children,
- 'app_label': self.app_label,
- 'available_children': self.available_children
- })
- context.update(csrf(context['request']))
- return render_to_string('jet.dashboard/dashboard_tools.html', context)
- def media(self):
- unique_css = OrderedSet()
- unique_js = OrderedSet()
- for js in getattr(self.Media, 'js', ()):
- unique_js.add(js)
- for css in getattr(self.Media, 'css', ()):
- unique_css.add(css)
- for module in self.modules:
- for js in getattr(module.Media, 'js', ()):
- unique_js.add(js)
- for css in getattr(module.Media, 'css', ()):
- unique_css.add(css)
- class Media:
- css = list(unique_css)
- js = list(unique_js)
- return Media
- class AppIndexDashboard(Dashboard):
- def get_app_content_types(self):
- return self.app_label + '.*',
- def models(self):
- return self.app_label + '.*',
- class DefaultIndexDashboard(Dashboard):
- columns = 3
- def init_with_context(self, context):
- self.available_children.append(modules.LinkList)
- self.available_children.append(modules.Feed)
- site_name = get_admin_site_name(context)
- # append a link list module for "quick links"
- self.children.append(modules.LinkList(
- _('Quick links'),
- layout='inline',
- draggable=False,
- deletable=False,
- collapsible=False,
- children=[
- [_('Return to site'), '/'],
- [_('Change password'),
- reverse('%s:password_change' % site_name)],
- [_('Log out'), reverse('%s:logout' % site_name)],
- ],
- column=0,
- order=0
- ))
- # append an app list module for "Applications"
- self.children.append(modules.AppList(
- _('Applications'),
- exclude=('auth.*',),
- column=1,
- order=0
- ))
- # append an app list module for "Administration"
- self.children.append(modules.AppList(
- _('Administration'),
- models=('auth.*',),
- column=2,
- order=0
- ))
- # append a recent actions module
- self.children.append(modules.RecentActions(
- _('Recent Actions'),
- 10,
- column=0,
- order=1
- ))
- # append a feed module
- self.children.append(modules.Feed(
- _('Latest Django News'),
- feed_url='http://www.djangoproject.com/rss/weblog/',
- limit=5,
- column=1,
- order=1
- ))
- # append another link list module for "support".
- self.children.append(modules.LinkList(
- _('Support'),
- children=[
- {
- 'title': _('Django documentation'),
- 'url': 'http://docs.djangoproject.com/',
- 'external': True,
- },
- {
- 'title': _('Django "django-users" mailing list'),
- 'url': 'http://groups.google.com/group/django-users',
- 'external': True,
- },
- {
- 'title': _('Django irc channel'),
- 'url': 'irc://irc.freenode.net/django',
- 'external': True,
- },
- ],
- column=2,
- order=1
- ))
- class DefaultAppIndexDashboard(AppIndexDashboard):
- def init_with_context(self, context):
- self.available_children.append(modules.LinkList)
- self.children.append(modules.ModelList(
- title=_('Application models'),
- models=self.models(),
- column=0,
- order=0
- ))
- self.children.append(modules.RecentActions(
- include_list=self.get_app_content_types(),
- column=1,
- order=0
- ))
- class DashboardUrls(object):
- _urls = []
- def get_urls(self):
- return self._urls
- def register_url(self, url):
- self._urls.append(url)
- def register_urls(self, urls):
- self._urls.extend(urls)
- urls = DashboardUrls()
|