Ticket #15294: 15294.14.diff

File 15294.14.diff, 51.1 KB (added by Florian Apolloner, 11 years ago)

New patch, has one broken testcase, but that test is utterly broken during it's missuse of admin view classes

  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index cf7ea83..620dbf0 100644
    a b from django.contrib import messages 
    1111from django.views.decorators.csrf import csrf_protect
    1212from django.core.exceptions import PermissionDenied, ValidationError
    1313from django.core.paginator import Paginator
     14from django.core.urlresolvers import reverse
    1415from django.db import models, transaction, router
    1516from django.db.models.related import RelatedObject
    1617from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist
    class ModelAdmin(BaseModelAdmin): 
    775776            # redirect to the change-list page for this object. Otherwise,
    776777            # redirect to the admin index.
    777778            if self.has_change_permission(request, None):
    778                 post_url = '../'
     779                post_url = reverse('admin:%s_%s_changelist' %
     780                                   (opts.app_label, opts.module_name),
     781                                   current_app=self.admin_site.name)
    779782            else:
    780                 post_url = '../../../'
     783                post_url = reverse('admin:index',
     784                                   current_app=self.admin_site.name)
    781785            return HttpResponseRedirect(post_url)
    782786
    783787    def response_change(self, request, obj):
    class ModelAdmin(BaseModelAdmin): 
    786790        """
    787791        opts = obj._meta
    788792
    789         # Handle proxy models automatically created by .only() or .defer()
     793        # Handle proxy models automatically created by .only() or .defer().
     794        # Refs #14529
    790795        verbose_name = opts.verbose_name
     796        module_name = opts.module_name
    791797        if obj._deferred:
    792798            opts_ = opts.proxy_for_model._meta
    793799            verbose_name = opts_.verbose_name
     800            module_name = opts_.module_name
    794801
    795802        pk_value = obj._get_pk_val()
    796803
    class ModelAdmin(BaseModelAdmin): 
    804811        elif "_saveasnew" in request.POST:
    805812            msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(verbose_name), 'obj': obj}
    806813            self.message_user(request, msg)
    807             return HttpResponseRedirect("../%s/" % pk_value)
     814            return HttpResponseRedirect(reverse('admin:%s_%s_change' %
     815                                        (opts.app_label, module_name),
     816                                        args=(pk_value,),
     817                                        current_app=self.admin_site.name))
    808818        elif "_addanother" in request.POST:
    809819            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(verbose_name)))
    810             return HttpResponseRedirect("../add/")
     820            return HttpResponseRedirect(reverse('admin:%s_%s_add' %
     821                                        (opts.app_label, module_name),
     822                                        current_app=self.admin_site.name))
    811823        else:
    812824            self.message_user(request, msg)
    813825            # Figure out where to redirect. If the user has change permission,
    814826            # redirect to the change-list page for this object. Otherwise,
    815827            # redirect to the admin index.
    816828            if self.has_change_permission(request, None):
    817                 return HttpResponseRedirect('../')
     829                post_url = reverse('admin:%s_%s_changelist' %
     830                                   (opts.app_label, module_name),
     831                                   current_app=self.admin_site.name)
    818832            else:
    819                 return HttpResponseRedirect('../../../')
     833                post_url = reverse('admin:index',
     834                                   current_app=self.admin_site.name)
     835            return HttpResponseRedirect(post_url)
    820836
    821837    def response_action(self, request, queryset):
    822838        """
    class ModelAdmin(BaseModelAdmin): 
    9891005            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)})
    9901006
    9911007        if request.method == 'POST' and "_saveasnew" in request.POST:
    992             return self.add_view(request, form_url='../add/')
     1008            return self.add_view(request, form_url=reverse('admin:%s_%s_add' %
     1009                                    (opts.app_label, opts.module_name),
     1010                                    current_app=self.admin_site.name))
    9931011
    9941012        ModelForm = self.get_form(request, obj)
    9951013        formsets = []
    class ModelAdmin(BaseModelAdmin): 
    12451263            self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
    12461264
    12471265            if not self.has_change_permission(request, None):
    1248                 return HttpResponseRedirect("../../../../")
    1249             return HttpResponseRedirect("../../")
     1266                return HttpResponseRedirect(reverse('admin:index',
     1267                                                    current_app=self.admin_site.name))
     1268            return HttpResponseRedirect(reverse('admin:%s_%s_changelist' %
     1269                                        (opts.app_label, opts.module_name),
     1270                                        current_app=self.admin_site.name))
    12501271
    12511272        object_name = force_unicode(opts.verbose_name)
    12521273
    class ModelAdmin(BaseModelAdmin): 
    12911312            'module_name': capfirst(force_unicode(opts.verbose_name_plural)),
    12921313            'object': obj,
    12931314            'app_label': app_label,
     1315            'opts': opts,
    12941316        }
    12951317        context.update(extra_context or {})
    12961318        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 49c1e78..3ba9314 100644
    a b class AdminSite(object): 
    339339                # Check whether user has any perm for this module.
    340340                # If so, add the module to the model_list.
    341341                if True in perms.values():
     342                    info = (app_label, model._meta.module_name)
    342343                    model_dict = {
    343344                        'name': capfirst(model._meta.verbose_name_plural),
    344                         '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),
    345347                        'perms': perms,
    346348                    }
    347349                    if app_label in app_dict:
    class AdminSite(object): 
    349351                    else:
    350352                        app_dict[app_label] = {
    351353                            'name': app_label.title(),
    352                             'app_url': app_label + '/',
     354                            'app_url': reverse('admin:app_list', kwargs={'app_label': app_label}, current_app=self.name),
    353355                            'has_module_perms': has_module_perms,
    354356                            'models': [model_dict],
    355357                        }
    class AdminSite(object): 
    383385                    # Check whether user has any perm for this module.
    384386                    # If so, add the module to the model_list.
    385387                    if True in perms.values():
     388                        info = (app_label, model._meta.module_name)
    386389                        model_dict = {
    387390                            'name': capfirst(model._meta.verbose_name_plural),
    388                             '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),
    389393                            'perms': perms,
    390394                        }
    391395                        if app_dict:
  • 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 b18b0aa..32dbcd9 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n admin_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="{% url opts|admin_url:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
     17&rsaquo; <a href="{% url opts|admin_url:'changelist' %}{{ 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 4b3c429..3b50adc 100644
    a b  
    3232                {% if docsroot %}
    3333                    <a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
    3434                {% endif %}
    35                 <a href="{% url 'admin:password_change' %}">
    36                 {% trans 'Change password' %}</a> /
    37                 <a href="{% url 'admin:logout' %}">
    38                 {% 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>
    3937            {% endblock %}
    4038        </div>
    4139        {% endif %}
    4240        {% block nav-global %}{% endblock %}
    4341    </div>
    4442    <!-- END Header -->
    45     {% 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 %}
    4649    {% endif %}
    4750
    4851    {% 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 56661e9..71230e4 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n admin_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="{% url opts|admin_url:'changelist' %}">{{ 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 24c6d8c..6a92496 100644
    a b  
    11{% extends "admin/base_site.html" %}
    22{% load i18n admin_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="{% url cl.opts|admin_url:'add' %}{% 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..a4acb95 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="{% url opts|admin_url:'changelist' %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
     11&rsaquo; <a href="{% url opts|admin_url:'changelist' %}{{ 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..04a2ae7 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="{% url opts|admin_url:'changelist' %}">{{ 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 7164220..86c795b 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..e39471b 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="{% url opts|admin_url:'changelist' %}">{{ module_name }}</a>
     11&rsaquo; <a href="{% url opts|admin_url:'changelist' %}{{ 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..15e4649
    - +  
     1from django.core.urlresolvers import reverse, NoReverseMatch
     2from django import template
     3
     4register = template.Library()
     5
     6@register.filter
     7def admin_url(value, arg):
     8    return 'admin:%s_%s_%s' % (value.app_label, value.module_name, arg)
  • 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 28319be..9725865 100644
    a b def view_index(request): 
    136136            site_obj = GenericSite()
    137137        for (func, regex) in view_functions:
    138138            views.append({
    139                 'name': getattr(func, '__name__', func.__class__.__name__),
    140                 'module': func.__module__,
     139                'full_name': '%s.%s' % (func.__module__, getattr(func, '__name__', func.__class__.__name__)),
    141140                'site_id': settings_mod.SITE_ID,
    142141                'site': site_obj,
    143142                'url': simplify_regex(regex),
  • tests/regressiontests/admin_changelist/tests.py

    diff --git a/tests/regressiontests/admin_changelist/tests.py b/tests/regressiontests/admin_changelist/tests.py
    index 709fa76..f09d4a0 100644
    a b class ChangeListTests(TestCase): 
    326326            request.user = user
    327327            return request
    328328
    329         # Test with user 'noparents'
    330329        m = DynamicListDisplayChildAdmin(Child, admin.site)
     330        # Test with user 'noparents'
    331331        request = _mocked_authenticated_request(user_noparents)
    332332        response = m.changelist_view(request)
    333333        # XXX - Calling render here to avoid ContentNotRenderedError to be
    class ChangeListTests(TestCase): 
    336336        self.assertNotContains(response, 'Parent object')
    337337
    338338        # Test with user 'parents'
    339         m = DynamicListDisplayChildAdmin(Child, admin.site)
    340339        request = _mocked_authenticated_request(user_parents)
    341340        response = m.changelist_view(request)
    342341        # XXX - #15826
    343342        response.render()
    344343        self.assertContains(response, 'Parent object')
    345344
     345        admin.site.unregister(Child)
     346
    346347        # Test default implementation
    347348        m = ChildAdmin(Child, admin.site)
    348349        request = _mocked_authenticated_request(user_noparents)
  • 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_views/models.py

    diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
    index 8dc61e3..9f6fb0b 100644
    a b admin.site.register(Question) 
    896896admin.site.register(Answer)
    897897admin.site.register(PrePopulatedPost, PrePopulatedPostAdmin)
    898898admin.site.register(ComplexSortedPerson, ComplexSortedPersonAdmin)
     899# Since contrib.comments is in INSTALLED_APPS we need it's admin too
     900from django.contrib.comments import admin
  • tests/regressiontests/admin_views/tests.py

    diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
    index 22b65a6..33e6dc3 100644
    a b class SaveAsTests(TestCase): 
    590590        self.assertTrue(response.context['save_as'])
    591591        post_data = {'_saveasnew':'', 'name':'John M', 'gender':3, 'alive':'checked'}
    592592        response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data)
    593         self.assertEqual(response.context['form_url'], '../add/')
     593        self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/')
    594594
    595595class CustomModelAdminTest(AdminViewBasicTest):
    596596    urlbit = "admin2"
    class AdminViewPermissionsTest(TestCase): 
    835835        self.client.post('/test_admin/admin/', self.adduser_login)
    836836        addpage = self.client.get('/test_admin/admin/admin_views/article/add/')
    837837        self.assertEqual(addpage.status_code, 200)
    838         change_list_link = '<a href="../">Articles</a> &rsaquo;'
     838        change_list_link = '&rsaquo; <a href="/test_admin/admin/admin_views/article/">Articles</a>'
    839839        self.assertFalse(change_list_link in addpage.content,
    840840                    'User restricted to add permission is given link to change list view in breadcrumbs.')
    841841        post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
  • tests/urls.py

    diff --git a/tests/urls.py b/tests/urls.py
    index b3f719d..7a5d76f 100644
    a b  
    11from django.conf.urls.defaults import *
    22
     3# Fix problems with cached urlconfs and reverse:
     4from regressiontests.admin_views import customadmin, models
     5from regressiontests.generic_inline_admin import models
    36
    47urlpatterns = patterns('',
    58    # test_client modeltest urls
    urlpatterns = patterns('', 
    2932    # admin widget tests
    3033    (r'widget_admin/', include('regressiontests.admin_widgets.urls')),
    3134
     35    # admin custom URL tests
     36    (r'^custom_urls/', include('regressiontests.admin_custom_urls.urls')),
     37
    3238)
Back to Top