Ticket #2292: app_specific_index.diff

File app_specific_index.diff, 15.7 KB (added by jkocherhans, 9 years ago)

patch againt [3534]

  • django/contrib/admin/templatetags/adminapplist.py

     
    11from django import template
    2 from django.db.models import get_models
     2from django.db import models
     3from django.utils.text import capfirst
    34
    45register = template.Library()
    56
     7def get_app_label(app):
     8    """
     9    Get the app_label of a given app. This is pretty hackish.
     10    """
     11    app_models = models.get_models(app)
     12    return app_models[0]._meta.app_label
     13
     14def get_admin_app_models(app, user):
     15    model_list = []
     16    app_label = get_app_label(app)
     17    for m in models.get_models(app):
     18        if m._meta.admin:
     19            perms = {
     20                'add': user.has_perm("%s.%s" % (app_label, m._meta.get_add_permission())),
     21                'change': user.has_perm("%s.%s" % (app_label, m._meta.get_change_permission())),
     22                'delete': user.has_perm("%s.%s" % (app_label, m._meta.get_delete_permission())),
     23            }
     24            # Check whether user has any perm for this model.
     25            # If so, add the module to the model_list.
     26            if True in perms.values():
     27                model_list.append({
     28                    'name': capfirst(m._meta.verbose_name_plural),
     29                    'admin_url': '%s/%s/' % (app_label, m.__name__.lower()),
     30                    'perms': perms,
     31                })
     32    return model_list
     33
     34def sorted_model_list(model_list):
     35    # Sort using verbose decorate-sort-undecorate pattern
     36    # instead of key argument to sort() for python 2.3 compatibility
     37    decorated = [(x['name'], x) for x in model_list]
     38    decorated.sort()
     39    return [x for key, x in decorated]
     40
    641class AdminApplistNode(template.Node):
    742    def __init__(self, varname):
    843        self.varname = varname
    944
    1045    def render(self, context):
    11         from django.db import models
    12         from django.utils.text import capfirst
    1346        app_list = []
    1447        user = context['user']
    1548
    1649        for app in models.get_apps():
    17             # Determine the app_label.
    18             app_models = get_models(app)
    19             if not app_models:
    20                 continue
    21             app_label = app_models[0]._meta.app_label
    22 
    23             has_module_perms = user.has_module_perms(app_label)
    24 
    25             if has_module_perms:
    26                 model_list = []
    27                 for m in app_models:
    28                     if m._meta.admin:
    29                         perms = {
    30                             'add': user.has_perm("%s.%s" % (app_label, m._meta.get_add_permission())),
    31                             'change': user.has_perm("%s.%s" % (app_label, m._meta.get_change_permission())),
    32                             'delete': user.has_perm("%s.%s" % (app_label, m._meta.get_delete_permission())),
    33                         }
    34 
    35                         # Check whether user has any perm for this module.
    36                         # If so, add the module to the model_list.
    37                         if True in perms.values():
    38                             model_list.append({
    39                                 'name': capfirst(m._meta.verbose_name_plural),
    40                                 'admin_url': '%s/%s/' % (app_label, m.__name__.lower()),
    41                                 'perms': perms,
    42                             })
    43 
    44                 if model_list:
    45                     # Sort using verbose decorate-sort-undecorate pattern
    46                     # instead of key argument to sort() for python 2.3 compatibility
    47                     decorated = [(x['name'], x) for x in model_list]
    48                     decorated.sort()
    49                     model_list = [x for key, x in decorated]
    50 
    51                     app_list.append({
    52                         'name': app_label.title(),
    53                         'has_module_perms': has_module_perms,
    54                         'models': model_list,
    55                     })
     50            model_list = get_admin_app_models(app, user)
     51            if model_list:
     52                app_list.append({
     53                    'name': get_app_label(app).title(),
     54                    'models': sorted_model_list(model_list),
     55                })
    5656        context[self.varname] = app_list
    5757        return ''
    5858
     
    7777    return AdminApplistNode(tokens[2])
    7878
    7979register.tag('get_admin_app_list', get_admin_app_list)
     80
     81class AdminAppNode(template.Node):
     82    def __init__(self, app_label_varname, varname):
     83        self.app_label_varname = app_label_varname
     84        self.varname = varname
     85
     86    def render(self, context):
     87        user = context['user']
     88
     89        app_label = context[self.app_label_varname]
     90        app = models.get_app(app_label)
     91
     92        if user.has_module_perms(app_label):
     93            model_list = get_admin_app_models(app, user)
     94
     95        context[self.varname] = {
     96            'name': app_label.title(),
     97            'models': sorted_model_list(model_list),
     98        }
     99        return ''
     100
     101def get_admin_app(parser, token):
     102    """
     103    Returns an installed application if the current user has at least one
     104    permission for one of the application's models.
     105
     106    Syntax::
     107   
     108        {% get_admin_app [context_var_containing_app_label] as [context_var_containing_app] %}
     109
     110    Example usage::
     111
     112        {% get_admin_app app_label as admin_app %}
     113    """
     114    tokens = token.contents.split()
     115    if len(tokens) < 4:
     116        raise template.TemplateSyntaxError, "'%s' tag requires three arguments" % tokens[0]
     117    if tokens[2] != 'as':
     118        raise template.TemplateSyntaxError, "Second argument to '%s' tag must be 'as'" % tokens[0]
     119    return AdminAppNode(tokens[1], tokens[3])
     120
     121register.tag('get_admin_app', get_admin_app)
  • django/contrib/admin/urls.py

     
    3131    # "Add user" -- a special-case view
    3232    ('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'),
    3333
     34    # App index
     35    ('^([^/]+)/$', 'django.contrib.admin.views.main.app_index'),
     36
    3437    # Add/change/delete/history
    3538    ('^([^/]+)/([^/]+)/$', 'django.contrib.admin.views.main.change_list'),
    3639    ('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
  • django/contrib/admin/views/auth.py

     
    3636        'first_form_field_id': 'id_username',
    3737        'opts': User._meta,
    3838        'username_help_text': User._meta.get_field('username').help_text,
     39        'app_label': 'auth'
    3940    }, context_instance=template.RequestContext(request))
  • django/contrib/admin/views/main.py

     
    223223    return render_to_response('admin/index.html', {'title': _('Site administration')}, context_instance=template.RequestContext(request))
    224224index = staff_member_required(never_cache(index))
    225225
     226def app_index(request, app_label):
     227    ctx = template.RequestContext(request)
     228    extra_ctx = {
     229        'title': capfirst(app_label),
     230        'app_label': app_label,
     231    }
     232    return render_to_response(('admin/%s/app_index.html' % app_label,
     233                               'admin/app_index.html',), extra_ctx, ctx)
     234                               
     235app_index = staff_member_required(never_cache(app_index))
     236
    226237def add_stage(request, app_label, model_name, show_delete=False, form_url='', post_url=None, post_url_continue='../%s/', object_id_override=None):
    227238    model = models.get_model(app_label, model_name)
    228239    if model is None:
     
    288299        'form': form,
    289300        'is_popup': request.REQUEST.has_key('_popup'),
    290301        'show_delete': show_delete,
     302        'app_label': app_label
    291303    })
    292304
    293305    if object_id_override is not None:
     
    391403        'object_id': object_id,
    392404        'original': manipulator.original_object,
    393405        'is_popup': request.REQUEST.has_key('_popup'),
     406        'app_label': app_label,
    394407    })
    395408    return render_change_form(model, manipulator, c, change=True)
    396409change_stage = staff_member_required(never_cache(change_stage))
     
    515528        "deleted_objects": deleted_objects,
    516529        "perms_lacking": perms_needed,
    517530        "opts": model._meta,
     531        'app_label': app_label,
    518532    }
    519533    return render_to_response(["admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower() ),
    520534                               "admin/%s/delete_confirmation.html" % app_label ,
     
    535549        'action_list': action_list,
    536550        'module_name': capfirst(model._meta.verbose_name_plural),
    537551        'object': obj,
     552        'app_label': app_label,
    538553    }
    539554    return render_to_response(["admin/%s/%s/object_history.html" % (app_label, model._meta.object_name.lower()),
    540555                               "admin/%s/object_history.html" % app_label ,
     
    747762        'title': cl.title,
    748763        'is_popup': cl.is_popup,
    749764        'cl': cl,
     765        'app_label': app_label,
    750766    })
    751767    c.update({'has_add_permission': c['perms'][app_label][cl.opts.get_add_permission()]}),
    752768    return render_to_response(['admin/%s/%s/change_list.html' % (app_label, cl.opts.object_name.lower()),
  • django/contrib/admin/templates/admin/change_list.html

     
    33{% block stylesheet %}{% admin_media_prefix %}css/changelists.css{% endblock %}
    44{% block bodyclass %}change-list{% endblock %}
    55{% block userlinks %}<a href="../../doc/">{% trans 'Documentation' %}</a> / <a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
    6 {% if not is_popup %}{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> &rsaquo; {{ cl.opts.verbose_name_plural|capfirst|escape }}</div>{% endblock %}{% endif %}
     6{% if not is_popup %}{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> &rsaquo; <a href="../">{{ app_label|capfirst }}</a> &rsaquo; {{ cl.opts.verbose_name_plural|capfirst|escape }}</div>{% endblock %}{% endif %}
    77{% block coltype %}flex{% endblock %}
    88{% block content %}
    99<div id="content-main">
  • django/contrib/admin/templates/admin/object_history.html

     
    22{% load i18n %}
    33{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
    44{% block breadcrumbs %}
    5 <div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> &rsaquo; <a href="../../">{{ module_name|escape }}</a> &rsaquo; <a href="../">{{ object|escape|truncatewords:"18" }}</a> &rsaquo; {% trans 'History' %}</div>
     5<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> &rsaquo; <a href="../../../">{{ app_label|capfirst }}</a> &rsaquo; <a href="../../">{{ module_name|escape }}</a> &rsaquo; <a href="../">{{ object|escape|truncatewords:"18" }}</a> &rsaquo; {% trans 'History' %}</div>
    66{% endblock %}
    77
    88{% block content %}
  • django/contrib/admin/templates/admin/app_index.html

     
     1{% extends "admin/index.html" %}
     2{% load i18n %}
     3{% load adminapplist %}
     4
     5{% block userlinks %}<a href="../doc/">{% trans 'Documentation' %}</a> / <a href="../password_change/">{% trans 'Change password' %}</a> / <a href="../logout/">{% trans 'Log out' %}</a>{% endblock %}
     6{% block breadcrumbs %}{% if not is_popup %}
     7<div class="breadcrumbs">
     8     <a href="../">{% trans "Home" %}</a> &rsaquo;
     9     {{ app_label|capfirst }}
     10</div>
     11{% endif %}{% endblock %}
     12{% block content %}
     13<div id="content-main">
     14
     15{% get_admin_app app_label as app %}
     16
     17<div class="module">
     18    <table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
     19    <caption>{{ app.name }}</caption>
     20    {% for model in app.models %}
     21        <tr>
     22        {% if model.perms.change %}
     23            <th scope="row"><a href="../{{ model.admin_url }}">{{ model.name }}</a></th>
     24        {% else %}
     25            <th scope="row">{{ model.name }}</th>
     26        {% endif %}
     27
     28        {% if model.perms.add %}
     29            <td><a href="../{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
     30        {% else %}
     31            <td>&nbsp;</td>
     32        {% endif %}
     33
     34        {% if model.perms.change %}
     35            <td><a href="../{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
     36        {% else %}
     37            <td>&nbsp;</td>
     38        {% endif %}
     39        </tr>
     40    {% endfor %}
     41    </table>
     42</div>
     43
     44</div>
     45{% endblock %}
     46
     47{% block sidebar %}
     48<div id="content-related">
     49    <div class="module" id="recent-actions-module">
     50        <h2>{% trans 'Recent Actions' %}</h2>
     51        <h3>{% trans 'My Actions' %}</h3>
     52            {% load log %}
     53            {% get_admin_log 10 as admin_log for_user user %}
     54            {% if not admin_log %}
     55            <p>{% trans 'None available' %}</p>
     56            {% else %}
     57            <ul class="actionlist">
     58            {% for entry in admin_log %}
     59                <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="../{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr|escape }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{{ entry.content_type.name|capfirst|escape }}</span></li>
     60            {% endfor %}
     61            </ul>
     62            {% endif %}
     63    </div>
     64</div>
     65{% endblock %}
  • django/contrib/admin/templates/admin/change_form.html

     
    1111{% block breadcrumbs %}{% if not is_popup %}
    1212<div class="breadcrumbs">
    1313     <a href="../../../">{% trans "Home" %}</a> &rsaquo;
     14     <a href="../../">{{ app_label|capfirst }}</a> &rsaquo;
    1415     <a href="../">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
    1516     {% if add %}{% trans "Add" %} {{ opts.verbose_name|escape }}{% else %}{{ original|truncatewords:"18"|escape }}{% endif %}
    1617</div>
  • django/contrib/admin/templates/admin/delete_confirmation.html

     
    44{% block breadcrumbs %}
    55<div class="breadcrumbs">
    66     <a href="../../../../">{% trans "Home" %}</a> &rsaquo;
     7     <a href="../../../">{{ app_label|capfirst }}</a> &rsaquo;
    78     <a href="../../">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
    89     <a href="../">{{ object|escape|truncatewords:"18" }}</a> &rsaquo;
    910     {% trans 'Delete' %}
Back to Top