Ticket #15294: 15294.4.diff

File 15294.4.diff, 65.1 KB (added by Ramiro Morales, 11 years ago)

Updated patch, also available at https://github.com/ramiro/django/compare/master...bug%2Ft15294

  • django/contrib/admin/actions.py

    diff --git a/django/contrib/admin/actions.py b/django/contrib/admin/actions.py
    index bd661f3..5b56402 100644
    a b def delete_selected(modeladmin, request, queryset): 
    6969        "perms_lacking": perms_needed,
    7070        "protected": protected,
    7171        "opts": opts,
    72         "root_path": modeladmin.admin_site.root_path,
    7372        "app_label": app_label,
    7473        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
    7574    }
  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index 550f46a..5f40157 100644
    a b from django.contrib import messages 
    1010from django.views.decorators.csrf import csrf_protect
    1111from django.core.exceptions import PermissionDenied, ValidationError
    1212from django.core.paginator import Paginator
     13from django.core.urlresolvers import reverse
    1314from django.db import models, transaction, router
    1415from django.db.models.related import RelatedObject
    1516from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist
    class BaseModelAdmin(object): 
    154155        """
    155156        db = kwargs.get('using')
    156157        if db_field.name in self.raw_id_fields:
    157             kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel, using=db)
     158            kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel, self.admin_site,
     159                                                             using=db)
    158160        elif db_field.name in self.radio_fields:
    159161            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
    160162                'class': get_ul_class(self.radio_fields[db_field.name]),
    class BaseModelAdmin(object): 
    174176        db = kwargs.get('using')
    175177
    176178        if db_field.name in self.raw_id_fields:
    177             kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db)
     179            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, self.admin_site,
     180                                                             using=db)
    178181            kwargs['help_text'] = ''
    179182        elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
    180183            kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    class ModelAdmin(BaseModelAdmin): 
    726729            'content_type_id': ContentType.objects.get_for_model(self.model).id,
    727730            'save_as': self.save_as,
    728731            'save_on_top': self.save_on_top,
    729             'root_path': self.admin_site.root_path,
    730732        })
    731733        if add and self.add_form_template is not None:
    732734            form_template = self.add_form_template
    class ModelAdmin(BaseModelAdmin): 
    769771            # redirect to the change-list page for this object. Otherwise,
    770772            # redirect to the admin index.
    771773            if self.has_change_permission(request, None):
    772                 post_url = '../'
     774                post_url = reverse('admin:%s_%s_changelist' %
     775                                   (opts.app_label, opts.module_name),
     776                                   current_app=self.admin_site.name)
    773777            else:
    774                 post_url = '../../../'
     778                post_url = reverse('admin:index',
     779                                   current_app=self.admin_site.name)
    775780            return HttpResponseRedirect(post_url)
    776781
    777782    def response_change(self, request, obj):
    class ModelAdmin(BaseModelAdmin): 
    780785        """
    781786        opts = obj._meta
    782787
    783         # Handle proxy models automatically created by .only() or .defer()
     788        # Handle proxy models automatically created by .only() or .defer().
     789        # Refs #14529
    784790        verbose_name = opts.verbose_name
     791        module_name = opts.module_name
    785792        if obj._deferred:
    786793            opts_ = opts.proxy_for_model._meta
    787794            verbose_name = opts_.verbose_name
     795            module_name = opts_.module_name
    788796
    789797        pk_value = obj._get_pk_val()
    790798
    class ModelAdmin(BaseModelAdmin): 
    798806        elif "_saveasnew" in request.POST:
    799807            msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(verbose_name), 'obj': obj}
    800808            self.message_user(request, msg)
    801             return HttpResponseRedirect("../%s/" % pk_value)
     809            return HttpResponseRedirect(reverse('admin:%s_%s_change' %
     810                                        (opts.app_label, module_name),
     811                                        args=(pk_value,),
     812                                        current_app=self.admin_site.name))
    802813        elif "_addanother" in request.POST:
    803814            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(verbose_name)))
    804             return HttpResponseRedirect("../add/")
     815            return HttpResponseRedirect(reverse('admin:%s_%s_add' %
     816                                        (opts.app_label, module_name),
     817                                        current_app=self.admin_site.name))
    805818        else:
    806819            self.message_user(request, msg)
    807820            # Figure out where to redirect. If the user has change permission,
    808821            # redirect to the change-list page for this object. Otherwise,
    809822            # redirect to the admin index.
    810823            if self.has_change_permission(request, None):
    811                 return HttpResponseRedirect('../')
     824                post_url = reverse('admin:%s_%s_changelist' %
     825                                   (opts.app_label, module_name),
     826                                   current_app=self.admin_site.name)
    812827            else:
    813                 return HttpResponseRedirect('../../../')
     828                post_url = reverse('admin:index',
     829                                   current_app=self.admin_site.name)
     830            return HttpResponseRedirect(post_url)
    814831
    815832    def response_action(self, request, queryset):
    816833        """
    class ModelAdmin(BaseModelAdmin): 
    962979            'media': mark_safe(media),
    963980            'inline_admin_formsets': inline_admin_formsets,
    964981            'errors': helpers.AdminErrorList(form, formsets),
    965             'root_path': self.admin_site.root_path,
    966982            'app_label': opts.app_label,
    967983        }
    968984        context.update(extra_context or {})
    class ModelAdmin(BaseModelAdmin): 
    9841000            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)})
    9851001
    9861002        if request.method == 'POST' and "_saveasnew" in request.POST:
    987             return self.add_view(request, form_url='../add/')
     1003            return self.add_view(request, form_url=reverse('admin:%s_%s_add' %
     1004                                    (opts.app_label, opts.module_name),
     1005                                    current_app=self.admin_site.name))
    9881006
    9891007        ModelForm = self.get_form(request, obj)
    9901008        formsets = []
    class ModelAdmin(BaseModelAdmin): 
    10531071            'media': mark_safe(media),
    10541072            'inline_admin_formsets': inline_admin_formsets,
    10551073            'errors': helpers.AdminErrorList(form, formsets),
    1056             'root_path': self.admin_site.root_path,
    10571074            'app_label': opts.app_label,
    10581075        }
    10591076        context.update(extra_context or {})
    class ModelAdmin(BaseModelAdmin): 
    11951212            'cl': cl,
    11961213            'media': media,
    11971214            'has_add_permission': self.has_add_permission(request),
    1198             'root_path': self.admin_site.root_path,
    11991215            'app_label': app_label,
    12001216            'action_form': action_form,
    12011217            'actions_on_top': self.actions_on_top,
    class ModelAdmin(BaseModelAdmin): 
    12421258            self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
    12431259
    12441260            if not self.has_change_permission(request, None):
    1245                 return HttpResponseRedirect("../../../../")
    1246             return HttpResponseRedirect("../../")
     1261                return HttpResponseRedirect(reverse('admin:index',
     1262                                                    current_app=self.admin_site.name))
     1263            return HttpResponseRedirect(reverse('admin:%s_%s_changelist' %
     1264                                        (opts.app_label, opts.module_name),
     1265                                        current_app=self.admin_site.name))
    12471266
    12481267        object_name = force_unicode(opts.verbose_name)
    12491268
    class ModelAdmin(BaseModelAdmin): 
    12601279            "perms_lacking": perms_needed,
    12611280            "protected": protected,
    12621281            "opts": opts,
    1263             "root_path": self.admin_site.root_path,
    12641282            "app_label": app_label,
    12651283        }
    12661284        context.update(extra_context or {})
    class ModelAdmin(BaseModelAdmin): 
    12881306            'action_list': action_list,
    12891307            'module_name': capfirst(force_unicode(opts.verbose_name_plural)),
    12901308            'object': obj,
    1291             'root_path': self.admin_site.root_path,
    12921309            'app_label': app_label,
     1310            "opts": opts,
    12931311        }
    12941312        context.update(extra_context or {})
    12951313        return TemplateResponse(request, self.object_history_template or [
  • django/contrib/admin/sites.py

    diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
    index a0338ee..3ba9314 100644
    a b class AdminSite(object): 
    3939    password_change_template = None
    4040    password_change_done_template = None
    4141
    42     def __init__(self, name=None, app_name='admin'):
     42    def __init__(self, name='admin', app_name='admin'):
    4343        self._registry = {} # model_class class -> admin_class instance
    44         self.root_path = None
    45         if name is None:
    46             self.name = 'admin'
    47         else:
    48             self.name = name
     44        self.name = name
    4945        self.app_name = app_name
    5046        self._actions = {'delete_selected': actions.delete_selected}
    5147        self._global_actions = self._actions.copy()
    class AdminSite(object): 
    254250        Handles the "change password" task -- both form display and validation.
    255251        """
    256252        from django.contrib.auth.views import password_change
    257         if self.root_path is not None:
    258             url = '%spassword_change/done/' % self.root_path
    259         else:
    260             url = reverse('admin:password_change_done', current_app=self.name)
     253        url = reverse('admin:password_change_done', current_app=self.name)
    261254        defaults = {
    262255            'current_app': self.name,
    263256            'post_change_redirect': url
    class AdminSite(object): 
    316309        from django.contrib.auth.views import login
    317310        context = {
    318311            'title': _('Log in'),
    319             'root_path': self.root_path,
    320312            'app_path': request.get_full_path(),
    321313            REDIRECT_FIELD_NAME: request.get_full_path(),
    322314        }
    class AdminSite(object): 
    347339                # Check whether user has any perm for this module.
    348340                # If so, add the module to the model_list.
    349341                if True in perms.values():
     342                    info = (app_label, model._meta.module_name)
    350343                    model_dict = {
    351344                        'name': capfirst(model._meta.verbose_name_plural),
    352                         'admin_url': mark_safe('%s/%s/' % (app_label, model.__name__.lower())),
     345                        'admin_url': reverse('admin:%s_%s_changelist' % info, current_app=self.name),
     346                        'add_url': reverse('admin:%s_%s_add' % info, current_app=self.name),
    353347                        'perms': perms,
    354348                    }
    355349                    if app_label in app_dict:
    class AdminSite(object): 
    357351                    else:
    358352                        app_dict[app_label] = {
    359353                            'name': app_label.title(),
    360                             'app_url': app_label + '/',
     354                            'app_url': reverse('admin:app_list', kwargs={'app_label': app_label}, current_app=self.name),
    361355                            'has_module_perms': has_module_perms,
    362356                            'models': [model_dict],
    363357                        }
    class AdminSite(object): 
    373367        context = {
    374368            'title': _('Site administration'),
    375369            'app_list': app_list,
    376             'root_path': self.root_path,
    377370        }
    378371        context.update(extra_context or {})
    379372        return TemplateResponse(request, [
    class AdminSite(object): 
    392385                    # Check whether user has any perm for this module.
    393386                    # If so, add the module to the model_list.
    394387                    if True in perms.values():
     388                        info = (app_label, model._meta.module_name)
    395389                        model_dict = {
    396390                            'name': capfirst(model._meta.verbose_name_plural),
    397                             'admin_url': '%s/' % model.__name__.lower(),
     391                            'admin_url': reverse('admin:%s_%s_changelist' % info, current_app=self.name),
     392                            'add_url': reverse('admin:%s_%s_add' % info, current_app=self.name),
    398393                            'perms': perms,
    399394                        }
    400395                        if app_dict:
    class AdminSite(object): 
    416411        context = {
    417412            'title': _('%s administration') % capfirst(app_label),
    418413            'app_list': [app_dict],
    419             'root_path': self.root_path,
    420414        }
    421415        context.update(extra_context or {})
    422416
  • django/contrib/admin/templates/admin/500.html

    diff --git a/django/contrib/admin/templates/admin/500.html b/django/contrib/admin/templates/admin/500.html
    index b30e431..eeb9e8d 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
    34
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans "Home" %}</a> &rsaquo; {% trans "Server error" %}</div>{% endblock %}
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Server error' %}
     9</div>
     10{% endblock %}
    511
    612{% block title %}{% trans 'Server error (500)' %}{% endblock %}
    713
  • django/contrib/admin/templates/admin/app_index.html

    diff --git a/django/contrib/admin/templates/admin/app_index.html b/django/contrib/admin/templates/admin/app_index.html
    index 120433d..4616b16 100644
    a b  
    1 {% extends "admin/index.html" %}
    2 {% load i18n %}
     1{% extends "admin/index.html" %}
     2{% load i18n %}
     3{% load url from future %}
    34
    45{% if not is_popup %}
    5 
    66{% block breadcrumbs %}
    7 <div class="breadcrumbs"><a href="../">
    8 {% trans "Home" %}</a> &rsaquo;
     7<div class="breadcrumbs">
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo;
    910{% for app in app_list %}
    1011{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
    11 {% endfor %}</div>{% endblock %}
    12 
    13 {% endif %}
     12{% endfor %}
     13</div>
     14{% endblock %}
     15{% endif %}
    1416
    15 {% block sidebar %}{% endblock %}
    16  No newline at end of file
     17{% block sidebar %}{% endblock %}
  • django/contrib/admin/templates/admin/auth/user/change_password.html

    diff --git a/django/contrib/admin/templates/admin/auth/user/change_password.html b/django/contrib/admin/templates/admin/auth/user/change_password.html
    index c280f50..18f8b80 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n static admin_modify %}
    33{% load url from future %}
     4{% load admin_urls %}
     5
    46{% block extrahead %}{{ block.super }}
    57{% url 'admin:jsi18n' as jsi18nurl %}
    68<script type="text/javascript" src="{{ jsi18nurl|default:"../../../../jsi18n/" }}"></script>
    79{% endblock %}
    810{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
    911{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
    10 {% block breadcrumbs %}{% if not is_popup %}
    11 <div class="breadcrumbs">
    12      <a href="../../../../">{% trans "Home" %}</a> &rsaquo;
    13      <a href="../../../">{{ opts.app_label|capfirst|escape }}</a> &rsaquo;
    14      <a href="../../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
    15      <a href="../">{{ original|truncatewords:"18" }}</a> &rsaquo;
    16     {% trans 'Change password' %}
     12{% if not is_popup %}
     13{% block breadcrumbs %}
     14<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     15&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_label|capfirst|escape }}</a>
     16&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}">{{ opts.verbose_name_plural|capfirst }}</a>
     17&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}{{ original.pk }}">{{ original|truncatewords:"18" }}</a>
     18&rsaquo; {% trans 'Change password' %}
    1719</div>
    18 {% endif %}{% endblock %}
     20{% endblock %}
     21{% endif %}
    1922{% block content %}<div id="content-main">
    2023<form action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %}
    2124<div>
  • django/contrib/admin/templates/admin/base.html

    diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html
    index 9034ae8..d0feb1c 100644
    a b  
    3232                {% if docsroot %}
    3333                    <a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
    3434                {% endif %}
    35                 {% url 'admin:password_change' as password_change_url %}
    36                 {% if password_change_url %}
    37                     <a href="{{ password_change_url }}">
    38                 {% else %}
    39                     <a href="{{ root_path }}password_change/">
    40                 {% endif %}
    41                 {% trans 'Change password' %}</a> /
    42                 {% url 'admin:logout' as logout_url %}
    43                 {% if logout_url %}
    44                     <a href="{{ logout_url }}">
    45                 {% else %}
    46                     <a href="{{ root_path }}logout/">
    47                 {% endif %}
    48                 {% trans 'Log out' %}</a>
     35                <a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a> /
     36                <a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
    4937            {% endblock %}
    5038        </div>
    5139        {% endif %}
    5240        {% block nav-global %}{% endblock %}
    5341    </div>
    5442    <!-- END Header -->
    55     {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} &rsaquo; {{ title }}{% endif %}</div>{% endblock %}
     43    {% block breadcrumbs %}
     44    <div class="breadcrumbs">
     45    <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     46    {% if title %} &rsaquo; {{ title }}{% endif %}
     47    </div>
     48    {% endblock %}
    5649    {% endif %}
    5750
    5851    {% block messages %}
  • django/contrib/admin/templates/admin/change_form.html

    diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
    index c5e428d..5a3b1ab 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n static admin_modify %}
    33{% load url from future %}
     4{% load admin_urls %}
    45
    56{% block extrahead %}{{ block.super }}
    67{% url 'admin:jsi18n' as jsi18nurl %}
     
    1415
    1516{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
    1617
    17 {% block breadcrumbs %}{% if not is_popup %}
    18 <div class="breadcrumbs">
    19      <a href="../../../">{% trans "Home" %}</a> &rsaquo;
    20      <a href="../../">{{ app_label|capfirst|escape }}</a> &rsaquo;
    21      {% if has_change_permission %}<a href="../">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %} &rsaquo;
    22      {% if add %}{% trans "Add" %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
     18{% if not is_popup %}
     19{% block breadcrumbs %}
     20<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     21&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ app_label|capfirst|escape }}</a>
     22&rsaquo; {% if has_change_permission %}<a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
     23&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
    2324</div>
    24 {% endif %}{% endblock %}
     25{% endblock %}
     26{% endif %}
    2527
    2628{% block content %}<div id="content-main">
    2729{% block object-tools %}
  • django/contrib/admin/templates/admin/change_list.html

    diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html
    index 29af47f..299e564 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n static admin_list %}
    33{% load url from future %}
     4{% load admin_urls %}
     5
    46{% block extrastyle %}
    57  {{ block.super }}
    68  <link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}" />
     
    3638{% block bodyclass %}change-list{% endblock %}
    3739
    3840{% if not is_popup %}
    39   {% block breadcrumbs %}
    40     <div class="breadcrumbs">
    41       <a href="../../">
    42         {% trans "Home" %}
    43       </a>
    44        &rsaquo;
    45        <a href="../">
    46          {{ app_label|capfirst }}
    47       </a>
    48       &rsaquo;
    49       {{ cl.opts.verbose_name_plural|capfirst }}
    50     </div>
    51   {% endblock %}
     41{% block breadcrumbs %}
     42<div class="breadcrumbs">
     43<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     44&rsaquo; <a href="{% url 'admin:app_list' app_label=cl.opts.app_label %}">{{ app_label|capfirst|escape }}</a>
     45&rsaquo; {{ cl.opts.verbose_name_plural|capfirst }}
     46</div>
     47{% endblock %}
    5248{% endif %}
    5349
    5450{% block coltype %}flex{% endblock %}
     
    6056        <ul class="object-tools">
    6157          {% block object-tools-items %}
    6258            <li>
    63               <a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">
     59              <a href="{% model_url 'admin:%s_%s_add' cl.opts.app_label cl.opts.module_name %}{% if is_popup %}?_popup=1{% endif %}" class="addlink">
    6460                {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
    6561              </a>
    6662            </li>
  • django/contrib/admin/templates/admin/delete_confirmation.html

    diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html
    index 0e6d47e..a1e4337 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
     4{% load admin_urls %}
    35
    46{% block breadcrumbs %}
    57<div class="breadcrumbs">
    6      <a href="../../../../">{% trans "Home" %}</a> &rsaquo;
    7      <a href="../../../">{{ app_label|capfirst }}</a> &rsaquo;
    8      <a href="../../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
    9      <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo;
    10     {% trans 'Delete' %}
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ app_label|capfirst }}</a>
     10&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
     11&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}{{ object.pk }}">{{ object|truncatewords:"18" }}</a>
     12&rsaquo; {% trans 'Delete' %}
    1113</div>
    1214{% endblock %}
    1315
  • django/contrib/admin/templates/admin/delete_selected_confirmation.html

    diff --git a/django/contrib/admin/templates/admin/delete_selected_confirmation.html b/django/contrib/admin/templates/admin/delete_selected_confirmation.html
    index 127519b..0a5d097 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n l10n %}
     3{% load url from future %}
     4{% load admin_urls %}
    35
    46{% block breadcrumbs %}
    57<div class="breadcrumbs">
    6      <a href="../../">{% trans "Home" %}</a> &rsaquo;
    7      <a href="../">{{ app_label|capfirst }}</a> &rsaquo;
    8      <a href="./">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
    9     {% trans 'Delete multiple objects' %}
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo; <a href="{% url 'admin:app_list' app_label=app_label %}">{{ app_label|capfirst|escape }}</a>
     10&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' app_label opts.module_name %}">{{ opts.verbose_name_plural|capfirst }}</a>
     11&rsaquo; {% trans 'Delete multiple objects' %}
    1012</div>
    1113{% endblock %}
    1214
  • django/contrib/admin/templates/admin/index.html

    diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html
    index 0f81a1a..b654329 100644
    a b  
    2626            {% endif %}
    2727
    2828            {% if model.perms.add %}
    29                 <td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
     29                <td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
    3030            {% else %}
    3131                <td>&nbsp;</td>
    3232            {% endif %}
  • django/contrib/admin/templates/admin/invalid_setup.html

    diff --git a/django/contrib/admin/templates/admin/invalid_setup.html b/django/contrib/admin/templates/admin/invalid_setup.html
    index f09b316..c2df4df 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
    34
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {{ title }}</div>{% endblock %}
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {{ title }}
     9</div>
     10{% endblock %}
    511
    612{% block content %}
    713<p>{% trans "Something's wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user." %}</p>
  • django/contrib/admin/templates/admin/object_history.html

    diff --git a/django/contrib/admin/templates/admin/object_history.html b/django/contrib/admin/templates/admin/object_history.html
    index 5ae7847..bb78f5c 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
     4{% load admin_urls %}
    35
    46{% block breadcrumbs %}
    57<div class="breadcrumbs">
    6     <a href="../../../../">{% trans 'Home' %}</a> &rsaquo;
    7     <a href="../../../">{{ app_label|capfirst }}</a> &rsaquo;
    8     <a href="../../">{{ module_name }}</a> &rsaquo;
    9     <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo;
    10     {% trans 'History' %}
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo; <a href="{% url 'admin:app_list' app_label=app_label %}">{{ app_label|capfirst|escape }}</a>
     10&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}">{{ module_name }}</a>
     11&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}{{ object.pk }}">{{ object|truncatewords:"18" }}</a>
     12&rsaquo; {% trans 'History' %}
    1113</div>
    1214{% endblock %}
    1315
  • django/contrib/admin/templates/registration/logged_out.html

    diff --git a/django/contrib/admin/templates/registration/logged_out.html b/django/contrib/admin/templates/registration/logged_out.html
    index d339ef0..e95d864 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
    34
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a></div>{% endblock %}
     5{% block breadcrumbs %}<div class="breadcrumbs"><a href="{% url 'admin:index' %}">{% trans 'Home' %}</a></div>{% endblock %}
    56
    67{% block content %}
    78
    89<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
    910
    10 <p><a href="../">{% trans 'Log in again' %}</a></p>
     11<p><a href="{% url 'admin:index' %}">{% trans 'Log in again' %}</a></p>
    1112
    1213{% endblock %}
  • django/contrib/admin/templates/registration/password_change_done.html

    diff --git a/django/contrib/admin/templates/registration/password_change_done.html b/django/contrib/admin/templates/registration/password_change_done.html
    index 0c0690d..863fc96 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
    33{% load url from future %}
    4 {% block userlinks %}{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %}{% trans 'Change password' %} / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
    5 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
     4{% block userlinks %}{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %}{% trans 'Change password' %} / <a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>{% endblock %}
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Password change' %}
     9</div>
     10{% endblock %}
    611
    712{% block title %}{% trans 'Password change successful' %}{% endblock %}
    813
  • django/contrib/admin/templates/registration/password_change_form.html

    diff --git a/django/contrib/admin/templates/registration/password_change_form.html b/django/contrib/admin/templates/registration/password_change_form.html
    index f76692d..0e4ea53 100644
    a b  
    22{% load i18n static %}
    33{% load url from future %}
    44{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
    5 {% block userlinks %}{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %} {% trans 'Change password' %} / <a href="../logout/">{% trans 'Log out' %}</a>{% endblock %}
    6 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
     5{% block userlinks %}{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %} {% trans 'Change password' %} / <a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>{% endblock %}
     6{% block breadcrumbs %}
     7<div class="breadcrumbs">
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo; {% trans 'Password change' %}
     10</div>
     11{% endblock %}
    712
    813{% block title %}{% trans 'Password change' %}{% endblock %}
    914
  • django/contrib/admin/templates/registration/password_reset_complete.html

    diff --git a/django/contrib/admin/templates/registration/password_reset_complete.html b/django/contrib/admin/templates/registration/password_reset_complete.html
    index fceb167..7c07707 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
    34
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Password reset' %}
     9</div>
     10{% endblock %}
    511
    612{% block title %}{% trans 'Password reset complete' %}{% endblock %}
    713
  • django/contrib/admin/templates/registration/password_reset_confirm.html

    diff --git a/django/contrib/admin/templates/registration/password_reset_confirm.html b/django/contrib/admin/templates/registration/password_reset_confirm.html
    index df9cf1b..d5299eb 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
    34
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset confirmation' %}</div>{% endblock %}
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Password reset confirmation' %}
     9</div>
     10{% endblock %}
    511
    612{% block title %}{% trans 'Password reset' %}{% endblock %}
    713
  • django/contrib/admin/templates/registration/password_reset_done.html

    diff --git a/django/contrib/admin/templates/registration/password_reset_done.html b/django/contrib/admin/templates/registration/password_reset_done.html
    index e223bdb..fd73af8 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
    34
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Password reset' %}
     9</div>
     10{% endblock %}
    511
    612{% block title %}{% trans 'Password reset successful' %}{% endblock %}
    713
  • django/contrib/admin/templates/registration/password_reset_form.html

    diff --git a/django/contrib/admin/templates/registration/password_reset_form.html b/django/contrib/admin/templates/registration/password_reset_form.html
    index d3a1284..2b591fe 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
    34
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Password reset' %}
     9</div>
     10{% endblock %}
    511
    612{% block title %}{% trans "Password reset" %}{% endblock %}
    713
  • new file django/contrib/admin/templatetags/admin_urls.py

    diff --git a/django/contrib/admin/templatetags/admin_urls.py b/django/contrib/admin/templatetags/admin_urls.py
    new file mode 100644
    index 0000000..90f30ed
    - +  
     1from django.core.urlresolvers import reverse, NoReverseMatch
     2from django import template
     3
     4register = template.Library()
     5
     6def model_url(context, fmt_string, app_name, model_name):
     7    try:
     8        return reverse(fmt_string % (app_name, model_name),
     9                current_app=context.current_app)
     10    except NoReverseMatch:
     11        return ''
     12register.simple_tag(takes_context=True)(model_url)
  • django/contrib/admin/widgets.py

    diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
    index bf48f16..15bccff 100644
    a b class ForeignKeyRawIdWidget(forms.TextInput): 
    113113    A Widget for displaying ForeignKeys in the "raw_id" interface rather than
    114114    in a <select> box.
    115115    """
    116     def __init__(self, rel, attrs=None, using=None):
     116    def __init__(self, rel, admin_site, attrs=None, using=None):
    117117        self.rel = rel
    118118        self.db = using
     119        self.admin_site = admin_site
    119120        super(ForeignKeyRawIdWidget, self).__init__(attrs)
    120121
    121122    def render(self, name, value, attrs=None):
     123        rel_to = self.rel.to
    122124        if attrs is None:
    123125            attrs = {}
    124         related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower())
    125         params = self.url_parameters()
    126         if params:
    127             url = u'?' + u'&amp;'.join([u'%s=%s' % (k, v) for k, v in params.items()])
    128         else:
    129             url = u''
    130         if "class" not in attrs:
    131             attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
    132         output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
    133         # TODO: "id_" is hard-coded here. This should instead use the correct
    134         # API to determine the ID dynamically.
    135         output.append(u'<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> '
    136                       % (related_url, url, name))
    137         output.append(u'<img src="%s" width="16" height="16" alt="%s" /></a>'
    138                       % (static('admin/img/selector-search.gif'), _('Lookup')))
     126        extra = []
     127        if rel_to in self.admin_site._registry: # If the related object has an admin interface:
     128            try:
     129                related_url = reverse('admin:%s_%s_changelist' %
     130                                        (rel_to._meta.app_label,
     131                                        rel_to._meta.module_name),
     132                                        current_app=self.admin_site.name)
     133            except NoReverseMatch:
     134                raise
     135
     136            params = self.url_parameters()
     137            if params:
     138                url = u'?' + u'&amp;'.join([u'%s=%s' % (k, v) for k, v in params.items()])
     139            else:
     140                url = u''
     141            if "class" not in attrs:
     142                attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript code looks for this hook.
     143            # TODO: "id_" is hard-coded here. This should instead use the correct
     144            # API to determine the ID dynamically.
     145            extra.append(u'<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> '
     146                         % (related_url, url, name))
     147            extra.append(u'<img src="%s" width="16" height="16" alt="%s" /></a>'
     148                         % (static('admin/img/selector-search.gif'), _('Lookup')))
     149        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] + extra
    139150        if value:
    140151            output.append(self.label_for_value(value))
    141152        return mark_safe(u''.join(output))
    class RelatedFieldWidgetWrapper(forms.Widget): 
    229240    def render(self, name, value, *args, **kwargs):
    230241        rel_to = self.rel.to
    231242        info = (rel_to._meta.app_label, rel_to._meta.object_name.lower())
    232         try:
    233             related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
    234         except NoReverseMatch:
    235             info = (self.admin_site.root_path, rel_to._meta.app_label, rel_to._meta.object_name.lower())
    236             related_url = '%s%s/%s/add/' % info
    237243        self.widget.choices = self.choices
    238244        output = [self.widget.render(name, value, *args, **kwargs)]
    239245        if self.can_add_related:
     246            related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
    240247            # TODO: "id_" is hard-coded here. This should instead use the correct
    241248            # API to determine the ID dynamically.
    242249            output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> '
  • django/contrib/admindocs/templates/admin_doc/bookmarklets.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/bookmarklets.html b/django/contrib/admindocs/templates/admin_doc/bookmarklets.html
    index 6447529..baa717c 100644
    a b  
    11{% extends "admin/base_site.html" %}
    2 
    3 {% block breadcrumbs %}{% load i18n %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> &rsaquo; <a href="../">{% trans "Documentation" %}</a> &rsaquo; {% trans "Bookmarklets" %}</div>{% endblock %}
     2{% load i18n %}
     3{% load url from future %}
     4
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     9&rsaquo; {% trans 'Bookmarklets' %}
     10</div>
     11{% endblock %}
    412{% block title %}{% trans "Documentation bookmarklets" %}{% endblock %}
    513
    614{% block content %}
  • django/contrib/admindocs/templates/admin_doc/index.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/index.html b/django/contrib/admindocs/templates/admin_doc/index.html
    index a8b21c3..652fbfd 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
    3 {% block breadcrumbs %}<div class="breadcrumbs"><a href="{{ root_path }}">Home</a> &rsaquo; Documentation</div>{% endblock %}
     3{% load url from future %}
     4
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Documentation' %}</a>
     9</div>
     10{% endblock %}
    411{% block title %}Documentation{% endblock %}
    512
    613{% block content %}
  • django/contrib/admindocs/templates/admin_doc/missing_docutils.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/missing_docutils.html b/django/contrib/admindocs/templates/admin_doc/missing_docutils.html
    index 97c9d47..34c18ff 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
    3 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> &rsaquo; Documentation</div>{% endblock %}
     3{% load url from future %}
     4
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; {% trans 'Documentation' %}</a>
     9</div>
    410{% block title %}Please install docutils{% endblock %}
    511
    612{% block content %}
  • django/contrib/admindocs/templates/admin_doc/model_detail.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/model_detail.html b/django/contrib/admindocs/templates/admin_doc/model_detail.html
    index 828df18..82cb405 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
     4
    35{% block extrahead %}
    46{{ block.super }}
    57<style type="text/css">
     
    810</style>
    911{% endblock %}
    1012
    11 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Models</a> &rsaquo; {{ name }}</div>{% endblock %}
     13{% block breadcrumbs %}
     14<div class="breadcrumbs">
     15<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     16&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     17&rsaquo; <a href="{% url 'django-admindocs-models-index' %}">{% trans 'Models' %}</a>
     18&rsaquo; {{ name }}
     19</div>
     20{% endblock %}
    1221
    1322{% block title %}Model: {{ name }}{% endblock %}
    1423
     
    4150</table>
    4251</div>
    4352
    44 <p class="small"><a href="../">&lsaquo; Back to Models Documentation</a></p>
     53<p class="small"><a href="{% url 'django-admindocs-models-index' %}">&lsaquo; Back to Models Documentation</a></p>
    4554</div>
    4655{% endblock %}
  • django/contrib/admindocs/templates/admin_doc/model_index.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/model_index.html b/django/contrib/admindocs/templates/admin_doc/model_index.html
    index 47c94c0..4eb3cf6 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
     4
    35{% block coltype %}colSM{% endblock %}
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; Models</div>{% endblock %}
     6
     7{% block breadcrumbs %}
     8<div class="breadcrumbs">
     9<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     10&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     11&rsaquo; {% trans 'Models' %}
     12</div>
     13{% endblock %}
    514
    615{% block title %}Models{% endblock %}
    716
     
    1928<table class="xfull">
    2029{% for model in group.list %}
    2130<tr>
    22 <th><a href="{{ model.app_label }}.{{ model.object_name.lower }}/">{{ model.object_name }}</a></th>
     31<th><a href="{% url 'django-admindocs-models-detail' app_label=model.app_label model_name=model.object_name.lower %}">{{ model.object_name }}</a></th>
    2332</tr>
    2433{% endfor %}
    2534</table>
  • django/contrib/admindocs/templates/admin_doc/template_detail.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/template_detail.html b/django/contrib/admindocs/templates/admin_doc/template_detail.html
    index c04dedc..307dd62 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
    3 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; Templates &rsaquo; {{ name }}</div>{% endblock %}
     3{% load url from future %}
     4
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     9&rsaquo; {% trans 'Templates' %}
     10&rsaquo; {{ name }}
     11</div>
     12{% endblock %}
    413
    514{% block title %}Template: {{ name }}{% endblock %}
    615
     
    1726    </ol>
    1827{% endfor %}
    1928
    20 <p class="small"><a href="../../">&lsaquo; Back to Documentation</a></p>
     29<p class="small"><a href="{% url 'django-admindocs-docroot' %}">&lsaquo; Back to Documentation</a></p>
    2130{% endblock %}
  • django/contrib/admindocs/templates/admin_doc/template_filter_index.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/template_filter_index.html b/django/contrib/admindocs/templates/admin_doc/template_filter_index.html
    index 46ccf0f..1809bc9 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
     4
    35{% block coltype %}colSM{% endblock %}
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; filters</div>{% endblock %}
     6{% block breadcrumbs %}
     7<div class="breadcrumbs">
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     10&rsaquo; {% trans 'Filters' %}
     11</div>
     12{% endblock %}
    513{% block title %}Template filters{% endblock %}
    614
    715{% block content %}
  • django/contrib/admindocs/templates/admin_doc/template_tag_index.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/template_tag_index.html b/django/contrib/admindocs/templates/admin_doc/template_tag_index.html
    index 676c025..18e5d95 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
     4
    35{% block coltype %}colSM{% endblock %}
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; Tags</div>{% endblock %}
     6{% block breadcrumbs %}
     7<div class="breadcrumbs">
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     10&rsaquo; {% trans 'Tags' %}
     11</div>
     12{% endblock %}
    513{% block title %}Template tags{% endblock %}
    614
    715{% block content %}
  • django/contrib/admindocs/templates/admin_doc/view_detail.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/view_detail.html b/django/contrib/admindocs/templates/admin_doc/view_detail.html
    index c6d080c..41c8121 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
    3 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Views</a> &rsaquo; {{ name }}</div>{% endblock %}
     3{% load url from future %}
     4
     5{% block breadcrumbs %}
     6<div class="breadcrumbs">
     7<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     8&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     9&rsaquo; <a href="{% url 'django-admindocs-views-index' %}">{% trans 'Views' %}</a>
     10&rsaquo; {{ name }}
     11</div>
     12{% endblock %}
    413{% block title %}View: {{ name }}{% endblock %}
    514
    615{% block content %}
     
    2130<p>{{ meta.Templates }}</p>
    2231{% endif %}
    2332
    24 <p class="small"><a href="../">&lsaquo; Back to Views Documentation</a></p>
     33<p class="small"><a href="{% url 'django-admindocs-views-index' %}">&lsaquo; Back to Views Documentation</a></p>
    2534{% endblock %}
  • django/contrib/admindocs/templates/admin_doc/view_index.html

    diff --git a/django/contrib/admindocs/templates/admin_doc/view_index.html b/django/contrib/admindocs/templates/admin_doc/view_index.html
    index 6b10fa6..e508c84 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n %}
     3{% load url from future %}
     4
    35{% block coltype %}colSM{% endblock %}
    4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; Views</div>{% endblock %}
     6{% block breadcrumbs %}
     7<div class="breadcrumbs">
     8<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
     9&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
     10&rsaquo; {% trans 'Views' %}
     11</div>
     12{% endblock %}
    513{% block title %}Views{% endblock %}
    614
    715{% block content %}
     
    2937
    3038{% for view in site_views.list|dictsort:"url" %}
    3139{% ifchanged %}
    32 <h3><a href="{{ view.module }}.{{ view.name }}/">{{ view.url }}</a></h3>
    33 <p class="small quiet">View function: {{ view.module }}.{{ view.name }}</p>
     40<h3><a href="{% url 'django-admindocs-views-detail' view=view.full_name %}">{{ view.url }}</a></h3>
     41<p class="small quiet">View function: {{ view.full_name }}</p>
    3442<p>{{ view.title }}</p>
    3543<hr />
    3644{% endifchanged %}
  • django/contrib/admindocs/views.py

    diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py
    index 079f7ab..d65c257 100644
    a b def view_index(request): 
    133133            site_obj = GenericSite()
    134134        for (func, regex) in view_functions:
    135135            views.append({
    136                 'name': getattr(func, '__name__', func.__class__.__name__),
    137                 'module': func.__module__,
     136                'full_name': '%s.%s' % (func.__module__, getattr(func, '__name__', func.__class__.__name__)),
    138137                'site_id': settings_mod.SITE_ID,
    139138                'site': site_obj,
    140139                'url': simplify_regex(regex),
  • new file tests/regressiontests/admin_custom_urls/__init__.py

    diff --git a/tests/regressiontests/admin_custom_urls/__init__.py b/tests/regressiontests/admin_custom_urls/__init__.py
    new file mode 100644
    index 0000000..792d600
    - +  
     1#
  • new file tests/regressiontests/admin_custom_urls/fixtures/actions.json

    diff --git a/tests/regressiontests/admin_custom_urls/fixtures/actions.json b/tests/regressiontests/admin_custom_urls/fixtures/actions.json
    new file mode 100644
    index 0000000..d803393
    - +  
     1[
     2  {
     3    "pk": "delete",
     4    "model": "admin_custom_urls.action",
     5    "fields": {
     6      "description": "Remove things."
     7    }
     8  },
     9  {
     10    "pk": "rename",
     11    "model": "admin_custom_urls.action",
     12    "fields": {
     13      "description": "Gives things other names."
     14    }
     15  },
     16  {
     17    "pk": "add",
     18    "model": "admin_custom_urls.action",
     19    "fields": {
     20      "description": "Add things."
     21    }
     22  },
     23  {
     24    "pk": "path/to/file/",
     25    "model": "admin_custom_urls.action",
     26    "fields": {
     27      "description": "An action with '/' in its name."
     28    }
     29  },
     30  {
     31    "pk": "path/to/html/document.html",
     32    "model": "admin_custom_urls.action",
     33    "fields": {
     34      "description": "An action with a name similar to a HTML doc path."
     35    }
     36  },
     37  {
     38    "pk": "javascript:alert('Hello world');\">Click here</a>",
     39    "model": "admin_custom_urls.action",
     40    "fields": {
     41      "description": "An action with a name suspected of being a XSS attempt"
     42    }
     43  }
     44]
     45 No newline at end of file
  • new file tests/regressiontests/admin_custom_urls/fixtures/users.json

    diff --git a/tests/regressiontests/admin_custom_urls/fixtures/users.json b/tests/regressiontests/admin_custom_urls/fixtures/users.json
    new file mode 100644
    index 0000000..72d86d7
    - +  
     1[
     2  {
     3    "pk": 100,
     4    "model": "auth.user",
     5    "fields": {
     6      "username": "super",
     7      "first_name": "Super",
     8      "last_name": "User",
     9      "is_active": true,
     10      "is_superuser": true,
     11      "is_staff": true,
     12      "last_login": "2007-05-30 13:20:10",
     13      "groups": [],
     14      "user_permissions": [],
     15      "password": "sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158",
     16      "email": "super@example.com",
     17      "date_joined": "2007-05-30 13:20:10"
     18    }
     19  }
     20]
  • new file tests/regressiontests/admin_custom_urls/models.py

    diff --git a/tests/regressiontests/admin_custom_urls/models.py b/tests/regressiontests/admin_custom_urls/models.py
    new file mode 100644
    index 0000000..f8c83a9
    - +  
     1from functools import update_wrapper
     2
     3from django.contrib import admin
     4from django.db import models
     5
     6
     7class Action(models.Model):
     8    name = models.CharField(max_length=50, primary_key=True)
     9    description = models.CharField(max_length=70)
     10
     11    def __unicode__(self):
     12        return self.name
     13
     14
     15class ActionAdmin(admin.ModelAdmin):
     16    """
     17    A ModelAdmin for the Action model that changes the URL of the add_view
     18    to '<app name>/<model name>/!add/'
     19    The Action model has a CharField PK.
     20    """
     21
     22    list_display = ('name', 'description')
     23
     24    def remove_url(self, name):
     25        """
     26        Remove all entries named 'name' from the ModelAdmin instance URL
     27        patterns list
     28        """
     29        return filter(lambda e: e.name != name, super(ActionAdmin, self).get_urls())
     30
     31    def get_urls(self):
     32        # Add the URL of our custom 'add_view' view to the front of the URLs
     33        # list.  Remove the existing one(s) first
     34        from django.conf.urls.defaults import patterns, url
     35
     36        def wrap(view):
     37            def wrapper(*args, **kwargs):
     38                return self.admin_site.admin_view(view)(*args, **kwargs)
     39            return update_wrapper(wrapper, view)
     40
     41        info = self.model._meta.app_label, self.model._meta.module_name
     42
     43        view_name = '%s_%s_add' % info
     44
     45        return patterns('',
     46            url(r'^!add/$', wrap(self.add_view), name=view_name),
     47        ) + self.remove_url(view_name)
     48
     49
     50admin.site.register(Action, ActionAdmin)
  • new file tests/regressiontests/admin_custom_urls/tests.py

    diff --git a/tests/regressiontests/admin_custom_urls/tests.py b/tests/regressiontests/admin_custom_urls/tests.py
    new file mode 100644
    index 0000000..cfc6b85
    - +  
     1from django.core.urlresolvers import reverse
     2from django.template.response import TemplateResponse
     3from django.test import TestCase
     4
     5from models import Action
     6
     7
     8class AdminCustomUrlsTest(TestCase):
     9    fixtures = ['users.json', 'actions.json']
     10
     11    def setUp(self):
     12        self.client.login(username='super', password='secret')
     13
     14    def tearDown(self):
     15        self.client.logout()
     16
     17    def testBasicAddGet(self):
     18        """
     19        A smoke test to ensure GET on the add_view works.
     20        """
     21        response = self.client.get('/custom_urls/admin/admin_custom_urls/action/!add/')
     22        self.assertIsInstance(response, TemplateResponse)
     23        self.assertEqual(response.status_code, 200)
     24
     25    def testAddWithGETArgs(self):
     26        response = self.client.get('/custom_urls/admin/admin_custom_urls/action/!add/', {'name': 'My Action'})
     27        self.assertEqual(response.status_code, 200)
     28        self.assertTrue(
     29            'value="My Action"' in response.content,
     30            "Couldn't find an input with the right value in the response."
     31        )
     32
     33    def testBasicAddPost(self):
     34        """
     35        A smoke test to ensure POST on add_view works.
     36        """
     37        post_data = {
     38            '_popup': u'1',
     39            "name": u'Action added through a popup',
     40            "description": u"Description of added action",
     41        }
     42        response = self.client.post('/custom_urls/admin/admin_custom_urls/action/!add/', post_data)
     43        self.assertEqual(response.status_code, 200)
     44        self.assertContains(response, 'dismissAddAnotherPopup')
     45        self.assertContains(response, 'Action added through a popup')
     46
     47    def testAdminUrlsNoClash(self):
     48        """
     49        Test that some admin URLs work correctly. The model has a CharField
     50        PK and the add_view URL has been customized.
     51        """
     52        # Should get the change_view for model instance with PK 'add', not show
     53        # the add_view
     54        response = self.client.get('/custom_urls/admin/admin_custom_urls/action/add/')
     55        self.assertEqual(response.status_code, 200)
     56        self.assertContains(response, 'Change action')
     57
     58        # Ditto, but use reverse() to build the URL
     59        path = reverse('admin:%s_action_change' % Action._meta.app_label,
     60                args=('add',))
     61        response = self.client.get(path)
     62        self.assertEqual(response.status_code, 200)
     63        self.assertContains(response, 'Change action')
     64
     65        # Should correctly get the change_view for the model instance with the
     66        # funny-looking PK
     67        path = reverse('admin:%s_action_change' % Action._meta.app_label,
     68                args=("path/to/html/document.html",))
     69        response = self.client.get(path)
     70        self.assertEqual(response.status_code, 200)
     71        self.assertContains(response, 'Change action')
     72        self.assertContains(response, 'value="path/to/html/document.html"')
  • new file tests/regressiontests/admin_custom_urls/urls.py

    diff --git a/tests/regressiontests/admin_custom_urls/urls.py b/tests/regressiontests/admin_custom_urls/urls.py
    new file mode 100644
    index 0000000..6c2761a
    - +  
     1from django.conf.urls.defaults import *
     2from django.contrib import admin
     3
     4urlpatterns = patterns('',
     5    (r'^admin/', include(admin.site.urls)),
     6)
     7
  • tests/regressiontests/admin_inlines/models.py

    diff --git a/tests/regressiontests/admin_inlines/models.py b/tests/regressiontests/admin_inlines/models.py
    index ee0abd1..9f7d080 100644
    a b class BookInline(admin.TabularInline): 
    4444class AuthorAdmin(admin.ModelAdmin):
    4545    inlines = [BookInline]
    4646
     47admin.site.register(Book)
    4748admin.site.register(Author, AuthorAdmin)
    4849
    4950class Holder(models.Model):
  • tests/regressiontests/admin_views/tests.py

    diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
    index 7128f04..85fb66c 100644
    a b class SaveAsTests(TestCase): 
    585585        self.assertTrue(response.context['save_as'])
    586586        post_data = {'_saveasnew':'', 'name':'John M', 'gender':3, 'alive':'checked'}
    587587        response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data)
    588         self.assertEqual(response.context['form_url'], '../add/')
     588        self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/')
    589589
    590590class CustomModelAdminTest(AdminViewBasicTest):
    591591    urlbit = "admin2"
    class AdminViewPermissionsTest(TestCase): 
    830830        self.client.post('/test_admin/admin/', self.adduser_login)
    831831        addpage = self.client.get('/test_admin/admin/admin_views/article/add/')
    832832        self.assertEqual(addpage.status_code, 200)
    833         change_list_link = '<a href="../">Articles</a> &rsaquo;'
     833        change_list_link = '&rsaquo; <a href="/test_admin/admin/admin_views/article/">Articles</a>'
    834834        self.assertFalse(change_list_link in addpage.content,
    835835                    'User restricted to add permission is given link to change list view in breadcrumbs.')
    836836        post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
  • tests/regressiontests/admin_widgets/tests.py

    diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py
    index 3cdb017..ac3baa0 100644
    a b class ForeignKeyRawIdWidgetTest(DjangoTestCase): 
    255255        )
    256256        rel = models.Album._meta.get_field('band').rel
    257257
    258         w = ForeignKeyRawIdWidget(rel)
     258        w = ForeignKeyRawIdWidget(rel, admin.site)
    259259        self.assertEqual(
    260260            conditional_escape(w.render('test', band.pk, attrs={})),
    261             '<input type="text" name="test" value="%(bandpk)s" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/band/?t=id" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Linkin Park</strong>' % dict(admin_media_prefix(), bandpk=band.pk),
     261            '<input type="text" name="test" value="%(bandpk)s" />&nbsp;<strong>Linkin Park</strong>' % {"bandpk": band.pk}
    262262        )
    263263
    264264    def test_relations_to_non_primary_key(self):
    class ForeignKeyRawIdWidgetTest(DjangoTestCase): 
    270270            barcode=87, name='Core', parent=apple
    271271        )
    272272        rel = models.Inventory._meta.get_field('parent').rel
    273         w = ForeignKeyRawIdWidget(rel)
     273        w = ForeignKeyRawIdWidget(rel, admin.site)
    274274        self.assertEqual(
    275275            w.render('test', core.parent_id, attrs={}),
    276             '<input type="text" name="test" value="86" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Apple</strong>' % admin_media_prefix(),
     276            '<input type="text" name="test" value="86" />&nbsp;<strong>Apple</strong>',
    277277        )
    278278
    279279
    280280    def test_proper_manager_for_label_lookup(self):
    281281        # see #9258
    282282        rel = models.Inventory._meta.get_field('parent').rel
    283         w = ForeignKeyRawIdWidget(rel)
     283        w = ForeignKeyRawIdWidget(rel, admin.site)
    284284
    285285        hidden = models.Inventory.objects.create(
    286286            barcode=93, name='Hidden', hidden=True
    class ForeignKeyRawIdWidgetTest(DjangoTestCase): 
    290290        )
    291291        self.assertEqual(
    292292            w.render('test', child_of_hidden.parent_id, attrs={}),
    293             '<input type="text" name="test" value="93" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Hidden</strong>' % admin_media_prefix(),
     293            '<input type="text" name="test" value="93" />&nbsp;<strong>Hidden</strong>',
    294294        )
    295295
    296296
    class ManyToManyRawIdWidgetTest(DjangoTestCase): 
    306306        band.members.add(m1, m2)
    307307        rel = models.Band._meta.get_field('members').rel
    308308
    309         w = ManyToManyRawIdWidget(rel)
     309        w = ManyToManyRawIdWidget(rel, admin.site)
    310310        self.assertEqual(
    311311            conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})),
    312             '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" /><a href="../../../admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk),
     312            '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" />' % {"m1pk": m1.pk, "m2pk": m2.pk},
    313313        )
    314314
    315315        self.assertEqual(
    316316            conditional_escape(w.render('test', [m1.pk])),
    317             '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" /><a href="../../../admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk),
     317            '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" />' % {"m1pk": m1.pk},
    318318        )
    319319
    320320        self.assertEqual(w._has_changed(None, None), False)
  • tests/regressiontests/admin_widgets/widgetadmin.py

    diff --git a/tests/regressiontests/admin_widgets/widgetadmin.py b/tests/regressiontests/admin_widgets/widgetadmin.py
    index 6f15d92..9082f8a 100644
    a b site.register(models.User) 
    2828site.register(models.Car, CarAdmin)
    2929site.register(models.CarTire, CarTireAdmin)
    3030site.register(models.Event, EventAdmin)
     31
     32site.register(models.Inventory)
     33site.register(models.Member)
     34site.register(models.Band)
  • tests/urls.py

    diff --git a/tests/urls.py b/tests/urls.py
    index b3f719d..929a913 100644
    a b urlpatterns = patterns('', 
    2929    # admin widget tests
    3030    (r'widget_admin/', include('regressiontests.admin_widgets.urls')),
    3131
     32    # admin custom URL tests
     33    (r'^custom_urls/', include('regressiontests.admin_custom_urls.urls')),
     34
    3235)
Back to Top