David Jean Louis avatar David Jean Louis committed c15e7dc Merge

* Merged kmike changes (fixes issue #70)
* Added a section for South migrate command (fixes issue #71)

Comments (0)

Files changed (10)

admin_tools/dashboard/dashboards.py

 from django.contrib.contenttypes.models import ContentType
 
 from admin_tools.dashboard import modules
-from admin_tools.utils import get_admin_site_name
+from admin_tools.utils import get_admin_site_name, uniquify
 
 
 class Dashboard(object):
         """
         return 'dashboard'
 
+    def _prepare_children(self):
+        """ Enumerates children without explicit id """
+        seen = set()
+        for id, module in enumerate(self.children):
+            module.id = uniquify(module.id or str(id+1), seen)
+            module._prepare_children()
+
 
 class AppIndexDashboard(Dashboard):
     """

admin_tools/dashboard/modules.py

 from django.utils.translation import ugettext_lazy as _
 from django.utils.itercompat import is_iterable
 
-from admin_tools.utils import AppListElementMixin
+from admin_tools.utils import AppListElementMixin, uniquify
 
 
 class DashboardModule(object):
     pre_content = None
     post_content = None
     children = None
+    id = None
 
     def __init__(self, title=None, **kwargs):
         if title is not None:
             self.title = title
+
         for key in kwargs:
             if hasattr(self.__class__, key):
                 setattr(self, key, kwargs[key])
+
         self.children = self.children or []
         self.css_classes = self.css_classes or []
         # boolean flag to ensure that the module is initialized only once
         ret += self.css_classes
         return ' '.join(ret)
 
+    def _prepare_children(self):
+        pass
+
 
 class Group(DashboardModule):
     """
                 return False
         return True
 
+    def _prepare_children(self):
+        # computes ids for children: generates them if they are not set
+        # and then prepends them with this group's id
+        seen = set()
+        for id, module in enumerate(self.children):
+            proposed_id = "%s_%s" % (self.id, module.id or id+1)
+            module.id = uniquify(proposed_id, seen)
+            module._prepare_children()
+
 
 class LinkList(DashboardModule):
     """

admin_tools/dashboard/templates/admin_tools/dashboard/dashboard.html

         {% spaceless %}
         {% for module in dashboard.children %}
         {% if not module.enabled %}
-        <li><a href="#" rel="module_{{ forloop.counter }}" class="addlink add-dashboard-module">{{ module.title }}</a></li>
+        <li><a href="#" rel="module_{{ moudle.id }}" class="addlink add-dashboard-module">{{ module.title }}</a></li>
         {% endif %}
         {% endfor %}
         {% endspaceless %}
 </div>
 <div id="{{ dashboard.get_id }}" class="dashboard-container">
     {% for module in dashboard.children %}
-{% admin_tools_render_dashboard_module module forloop.counter %}{% endfor %}
+{% admin_tools_render_dashboard_module module %}{% endfor %}
 </div>

admin_tools/dashboard/templates/admin_tools/dashboard/module.html

 {% if not module.is_empty %}
-    <div{% if index %} id="module_{{ index }}{% if subindex %}_{{ subindex }}{% endif %}"{% endif %} class="{{ module.render_css_classes }}">
+    <div id="module_{{ module.id }}" class="{{ module.render_css_classes }}">
         {% if module.show_title %}<h2>{{ module.title }}</h2>{% endif %}
         <div class="dashboard-module-content">
             {% spaceless %}

admin_tools/dashboard/templates/admin_tools/dashboard/modules/group.html

     {% ifequal module.display "tabs" %}
     <ul>
     {% for sub_module in module.children %}
-        {% if not sub_module.is_empty %}<li class="group-tabs-link"><a href="#module_{{ index }}_{{ forloop.counter }}">{{ sub_module.title }}</a></li>{% endif %}
+        {% if not sub_module.is_empty %}<li class="group-tabs-link"><a href="#module_{{ sub_module.id }}">{{ sub_module.title }}</a></li>{% endif %}
     {% endfor %}
     </ul>
     {% endifequal %}
     {% ifequal module.display "accordion" %}
     {% for sub_module in module.children %}
         {% if not sub_module.is_empty %}<span class="group-accordion-header"><a href="#">{{ sub_module.title }}</a></span>{% endif %}
-        {% admin_tools_render_dashboard_module sub_module index forloop.counter %}
+        {% admin_tools_render_dashboard_module sub_module %}
     {% endfor %}
     {% else %}
     {% for sub_module in module.children %}
-        {% admin_tools_render_dashboard_module sub_module index forloop.counter %}
+        {% admin_tools_render_dashboard_module sub_module %}
     {% endfor %}
     {% endifequal %}
     {% endspaceless %}

admin_tools/dashboard/templatetags/admin_tools_dashboard_tags.py

         dashboard = get_dashboard(context, location)
 
     dashboard.init_with_context(context)
+    dashboard._prepare_children()
 
     try:
         preferences = DashboardPreferences.objects.get(user=context['request'].user).data
 admin_tools_render_dashboard = tag_func(admin_tools_render_dashboard)
 
 
-def admin_tools_render_dashboard_module(context, module, index=None, subindex=None):
+def admin_tools_render_dashboard_module(context, module):
     """
     Template tag that renders a given dashboard module, it takes a
-    ``DashboardModule`` instance as first parameter and an integer ``index`` as
-    second parameter, that is the index of the module in the dashboard.
+    ``DashboardModule`` instance as first parameter.
     """
     module.init_with_context(context)
     context.update({
         'template': module.template,
         'module': module,
-        'index': index,
-        'subindex': subindex,
         'admin_url': reverse('%s:index' % get_admin_site_name(context)),
     })
     return context

admin_tools/dashboard/utils.py

 import types
 
 from django.conf import settings
-from django.contrib import admin
 from django.utils.importlib import import_module
 from django.utils.text import capfirst
 from django.core.urlresolvers import reverse
 
 from admin_tools.dashboard.registry import Registry
-from admin_tools.dashboard import Registry
 from admin_tools.utils import get_admin_site
 
-
 def get_dashboard(context, location):
     """
     Returns the dashboard that match the given ``location``
     app_label = None
     app_title = app['name']
     admin_site = get_admin_site(context=context)
-    
+
     for model, model_admin in admin_site._registry.items():
         if app['name'] == model._meta.app_label.title():
             split = model.__module__.find(model._meta.app_label)

admin_tools/utils.py

 from django.utils.importlib import import_module
 import warnings
 
+def uniquify(value, seen_values):
+    """ Adds value to seen_values set and ensures it is unique """
+    id = 1
+    new_value = value
+    while new_value in seen_values:
+        new_value = "%s%s" % (value, id)
+        id += 1
+    seen_values.add(new_value)
+    return new_value
 
 def get_admin_site(context=None, request=None):
     dashboard_cls = getattr(

docs/configuration.rst

 
     python manage.py syncdb
 
+django-admin-tools supports `South <http://south.aeracode.org>`_, so if you
+have South installed, make sure you run the following commands::
+
+    python manage.py migrate admin_tools.dashboard
+    python manage.py migrate admin_tools.menu
+
 Adding django-admin-tools to your urls.py file
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

docs/quickstart.rst

 
     python manage.py syncdb
 
+django-admin-tools supports `South <http://south.aeracode.org>`_, so if you
+have South installed, make sure you run the following commands::
+
+    python manage.py migrate admin_tools.dashboard
+    python manage.py migrate admin_tools.menu
+
 Adding django-admin-tools to your urls.py file
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.