diff --git a/django/contrib/admin/actions.py b/django/contrib/admin/actions.py
index bd661f3..5b56402 100644
--- a/django/contrib/admin/actions.py
+++ b/django/contrib/admin/actions.py
@@ -69,7 +69,6 @@ def delete_selected(modeladmin, request, queryset):
         "perms_lacking": perms_needed,
         "protected": protected,
         "opts": opts,
-        "root_path": modeladmin.admin_site.root_path,
         "app_label": app_label,
         'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
     }
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 550f46a..5f40157 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -10,6 +10,7 @@ from django.contrib import messages
 from django.views.decorators.csrf import csrf_protect
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.core.paginator import Paginator
+from django.core.urlresolvers import reverse
 from django.db import models, transaction, router
 from django.db.models.related import RelatedObject
 from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist
@@ -154,7 +155,8 @@ class BaseModelAdmin(object):
         """
         db = kwargs.get('using')
         if db_field.name in self.raw_id_fields:
-            kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel, using=db)
+            kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel, self.admin_site,
+                                                             using=db)
         elif db_field.name in self.radio_fields:
             kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                 'class': get_ul_class(self.radio_fields[db_field.name]),
@@ -174,7 +176,8 @@ class BaseModelAdmin(object):
         db = kwargs.get('using')
 
         if db_field.name in self.raw_id_fields:
-            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db)
+            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, self.admin_site,
+                                                             using=db)
             kwargs['help_text'] = ''
         elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
             kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
@@ -726,7 +729,6 @@ class ModelAdmin(BaseModelAdmin):
             'content_type_id': ContentType.objects.get_for_model(self.model).id,
             'save_as': self.save_as,
             'save_on_top': self.save_on_top,
-            'root_path': self.admin_site.root_path,
         })
         if add and self.add_form_template is not None:
             form_template = self.add_form_template
@@ -769,9 +771,12 @@ class ModelAdmin(BaseModelAdmin):
             # redirect to the change-list page for this object. Otherwise,
             # redirect to the admin index.
             if self.has_change_permission(request, None):
-                post_url = '../'
+                post_url = reverse('admin:%s_%s_changelist' %
+                                   (opts.app_label, opts.module_name),
+                                   current_app=self.admin_site.name)
             else:
-                post_url = '../../../'
+                post_url = reverse('admin:index',
+                                   current_app=self.admin_site.name)
             return HttpResponseRedirect(post_url)
 
     def response_change(self, request, obj):
@@ -780,11 +785,14 @@ class ModelAdmin(BaseModelAdmin):
         """
         opts = obj._meta
 
-        # Handle proxy models automatically created by .only() or .defer()
+        # Handle proxy models automatically created by .only() or .defer().
+        # Refs #14529
         verbose_name = opts.verbose_name
+        module_name = opts.module_name
         if obj._deferred:
             opts_ = opts.proxy_for_model._meta
             verbose_name = opts_.verbose_name
+            module_name = opts_.module_name
 
         pk_value = obj._get_pk_val()
 
@@ -798,19 +806,28 @@ class ModelAdmin(BaseModelAdmin):
         elif "_saveasnew" in request.POST:
             msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(verbose_name), 'obj': obj}
             self.message_user(request, msg)
-            return HttpResponseRedirect("../%s/" % pk_value)
+            return HttpResponseRedirect(reverse('admin:%s_%s_change' %
+                                        (opts.app_label, module_name),
+                                        args=(pk_value,),
+                                        current_app=self.admin_site.name))
         elif "_addanother" in request.POST:
             self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(verbose_name)))
-            return HttpResponseRedirect("../add/")
+            return HttpResponseRedirect(reverse('admin:%s_%s_add' %
+                                        (opts.app_label, module_name),
+                                        current_app=self.admin_site.name))
         else:
             self.message_user(request, msg)
             # Figure out where to redirect. If the user has change permission,
             # redirect to the change-list page for this object. Otherwise,
             # redirect to the admin index.
             if self.has_change_permission(request, None):
-                return HttpResponseRedirect('../')
+                post_url = reverse('admin:%s_%s_changelist' %
+                                   (opts.app_label, module_name),
+                                   current_app=self.admin_site.name)
             else:
-                return HttpResponseRedirect('../../../')
+                post_url = reverse('admin:index',
+                                   current_app=self.admin_site.name)
+            return HttpResponseRedirect(post_url)
 
     def response_action(self, request, queryset):
         """
@@ -962,7 +979,6 @@ class ModelAdmin(BaseModelAdmin):
             'media': mark_safe(media),
             'inline_admin_formsets': inline_admin_formsets,
             'errors': helpers.AdminErrorList(form, formsets),
-            'root_path': self.admin_site.root_path,
             'app_label': opts.app_label,
         }
         context.update(extra_context or {})
@@ -984,7 +1000,9 @@ class ModelAdmin(BaseModelAdmin):
             raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)})
 
         if request.method == 'POST' and "_saveasnew" in request.POST:
-            return self.add_view(request, form_url='../add/')
+            return self.add_view(request, form_url=reverse('admin:%s_%s_add' %
+                                    (opts.app_label, opts.module_name),
+                                    current_app=self.admin_site.name))
 
         ModelForm = self.get_form(request, obj)
         formsets = []
@@ -1053,7 +1071,6 @@ class ModelAdmin(BaseModelAdmin):
             'media': mark_safe(media),
             'inline_admin_formsets': inline_admin_formsets,
             'errors': helpers.AdminErrorList(form, formsets),
-            'root_path': self.admin_site.root_path,
             'app_label': opts.app_label,
         }
         context.update(extra_context or {})
@@ -1195,7 +1212,6 @@ class ModelAdmin(BaseModelAdmin):
             'cl': cl,
             'media': media,
             'has_add_permission': self.has_add_permission(request),
-            'root_path': self.admin_site.root_path,
             'app_label': app_label,
             'action_form': action_form,
             'actions_on_top': self.actions_on_top,
@@ -1242,8 +1258,11 @@ class ModelAdmin(BaseModelAdmin):
             self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
 
             if not self.has_change_permission(request, None):
-                return HttpResponseRedirect("../../../../")
-            return HttpResponseRedirect("../../")
+                return HttpResponseRedirect(reverse('admin:index',
+                                                    current_app=self.admin_site.name))
+            return HttpResponseRedirect(reverse('admin:%s_%s_changelist' %
+                                        (opts.app_label, opts.module_name),
+                                        current_app=self.admin_site.name))
 
         object_name = force_unicode(opts.verbose_name)
 
@@ -1260,7 +1279,6 @@ class ModelAdmin(BaseModelAdmin):
             "perms_lacking": perms_needed,
             "protected": protected,
             "opts": opts,
-            "root_path": self.admin_site.root_path,
             "app_label": app_label,
         }
         context.update(extra_context or {})
@@ -1288,8 +1306,8 @@ class ModelAdmin(BaseModelAdmin):
             'action_list': action_list,
             'module_name': capfirst(force_unicode(opts.verbose_name_plural)),
             'object': obj,
-            'root_path': self.admin_site.root_path,
             'app_label': app_label,
+            "opts": opts,
         }
         context.update(extra_context or {})
         return TemplateResponse(request, self.object_history_template or [
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index a0338ee..3ba9314 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -39,13 +39,9 @@ class AdminSite(object):
     password_change_template = None
     password_change_done_template = None
 
-    def __init__(self, name=None, app_name='admin'):
+    def __init__(self, name='admin', app_name='admin'):
         self._registry = {} # model_class class -> admin_class instance
-        self.root_path = None
-        if name is None:
-            self.name = 'admin'
-        else:
-            self.name = name
+        self.name = name
         self.app_name = app_name
         self._actions = {'delete_selected': actions.delete_selected}
         self._global_actions = self._actions.copy()
@@ -254,10 +250,7 @@ class AdminSite(object):
         Handles the "change password" task -- both form display and validation.
         """
         from django.contrib.auth.views import password_change
-        if self.root_path is not None:
-            url = '%spassword_change/done/' % self.root_path
-        else:
-            url = reverse('admin:password_change_done', current_app=self.name)
+        url = reverse('admin:password_change_done', current_app=self.name)
         defaults = {
             'current_app': self.name,
             'post_change_redirect': url
@@ -316,7 +309,6 @@ class AdminSite(object):
         from django.contrib.auth.views import login
         context = {
             'title': _('Log in'),
-            'root_path': self.root_path,
             'app_path': request.get_full_path(),
             REDIRECT_FIELD_NAME: request.get_full_path(),
         }
@@ -347,9 +339,11 @@ class AdminSite(object):
                 # Check whether user has any perm for this module.
                 # If so, add the module to the model_list.
                 if True in perms.values():
+                    info = (app_label, model._meta.module_name)
                     model_dict = {
                         'name': capfirst(model._meta.verbose_name_plural),
-                        'admin_url': mark_safe('%s/%s/' % (app_label, model.__name__.lower())),
+                        'admin_url': reverse('admin:%s_%s_changelist' % info, current_app=self.name),
+                        'add_url': reverse('admin:%s_%s_add' % info, current_app=self.name),
                         'perms': perms,
                     }
                     if app_label in app_dict:
@@ -357,7 +351,7 @@ class AdminSite(object):
                     else:
                         app_dict[app_label] = {
                             'name': app_label.title(),
-                            'app_url': app_label + '/',
+                            'app_url': reverse('admin:app_list', kwargs={'app_label': app_label}, current_app=self.name),
                             'has_module_perms': has_module_perms,
                             'models': [model_dict],
                         }
@@ -373,7 +367,6 @@ class AdminSite(object):
         context = {
             'title': _('Site administration'),
             'app_list': app_list,
-            'root_path': self.root_path,
         }
         context.update(extra_context or {})
         return TemplateResponse(request, [
@@ -392,9 +385,11 @@ class AdminSite(object):
                     # Check whether user has any perm for this module.
                     # If so, add the module to the model_list.
                     if True in perms.values():
+                        info = (app_label, model._meta.module_name)
                         model_dict = {
                             'name': capfirst(model._meta.verbose_name_plural),
-                            'admin_url': '%s/' % model.__name__.lower(),
+                            'admin_url': reverse('admin:%s_%s_changelist' % info, current_app=self.name),
+                            'add_url': reverse('admin:%s_%s_add' % info, current_app=self.name),
                             'perms': perms,
                         }
                         if app_dict:
@@ -416,7 +411,6 @@ class AdminSite(object):
         context = {
             'title': _('%s administration') % capfirst(app_label),
             'app_list': [app_dict],
-            'root_path': self.root_path,
         }
         context.update(extra_context or {})
 
diff --git a/django/contrib/admin/templates/admin/500.html b/django/contrib/admin/templates/admin/500.html
index b30e431..eeb9e8d 100644
--- a/django/contrib/admin/templates/admin/500.html
+++ b/django/contrib/admin/templates/admin/500.html
@@ -1,7 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans "Home" %}</a> &rsaquo; {% trans "Server error" %}</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Server error' %}
+</div>
+{% endblock %}
 
 {% block title %}{% trans 'Server error (500)' %}{% endblock %}
 
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/django/contrib/admin/templates/admin/app_index.html
+++ b/django/contrib/admin/templates/admin/app_index.html
@@ -1,15 +1,17 @@
-{% extends "admin/index.html" %} 
-{% load i18n %} 
+{% extends "admin/index.html" %}
+{% load i18n %}
+{% load url from future %}
 
 {% if not is_popup %}
-
 {% block breadcrumbs %}
-<div class="breadcrumbs"><a href="../">
-{% trans "Home" %}</a> &rsaquo; 
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo;
 {% for app in app_list %}
 {% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
-{% endfor %}</div>{% endblock %}
-
-{% endif %} 
+{% endfor %}
+</div>
+{% endblock %}
+{% endif %}
 
-{% block sidebar %}{% endblock %}
\ No newline at end of file
+{% block sidebar %}{% endblock %}
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/django/contrib/admin/templates/admin/auth/user/change_password.html
+++ b/django/contrib/admin/templates/admin/auth/user/change_password.html
@@ -1,21 +1,24 @@
 {% extends "admin/base_site.html" %}
 {% load i18n static admin_modify %}
 {% load url from future %}
+{% load admin_urls %}
+
 {% block extrahead %}{{ block.super }}
 {% url 'admin:jsi18n' as jsi18nurl %}
 <script type="text/javascript" src="{{ jsi18nurl|default:"../../../../jsi18n/" }}"></script>
 {% endblock %}
 {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
 {% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
-{% block breadcrumbs %}{% if not is_popup %}
-<div class="breadcrumbs">
-     <a href="../../../../">{% trans "Home" %}</a> &rsaquo;
-     <a href="../../../">{{ opts.app_label|capfirst|escape }}</a> &rsaquo;
-     <a href="../../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
-     <a href="../">{{ original|truncatewords:"18" }}</a> &rsaquo;
-     {% trans 'Change password' %}
+{% if not is_popup %}
+{% block breadcrumbs %}
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_label|capfirst|escape }}</a>
+&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}">{{ opts.verbose_name_plural|capfirst }}</a>
+&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}{{ original.pk }}">{{ original|truncatewords:"18" }}</a>
+&rsaquo; {% trans 'Change password' %}
 </div>
-{% endif %}{% endblock %}
+{% endblock %}
+{% endif %}
 {% block content %}<div id="content-main">
 <form action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %}
 <div>
diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html
index 9034ae8..d0feb1c 100644
--- a/django/contrib/admin/templates/admin/base.html
+++ b/django/contrib/admin/templates/admin/base.html
@@ -32,27 +32,20 @@
                 {% if docsroot %}
                     <a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
                 {% endif %}
-                {% url 'admin:password_change' as password_change_url %}
-                {% if password_change_url %}
-                    <a href="{{ password_change_url }}">
-                {% else %}
-                    <a href="{{ root_path }}password_change/">
-                {% endif %}
-                {% trans 'Change password' %}</a> /
-                {% url 'admin:logout' as logout_url %}
-                {% if logout_url %}
-                    <a href="{{ logout_url }}">
-                {% else %}
-                    <a href="{{ root_path }}logout/">
-                {% endif %}
-                {% trans 'Log out' %}</a>
+                <a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a> /
+                <a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
             {% endblock %}
         </div>
         {% endif %}
         {% block nav-global %}{% endblock %}
     </div>
     <!-- END Header -->
-    {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} &rsaquo; {{ title }}{% endif %}</div>{% endblock %}
+    {% block breadcrumbs %}
+    <div class="breadcrumbs">
+    <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+    {% if title %} &rsaquo; {{ title }}{% endif %}
+    </div>
+    {% endblock %}
     {% endif %}
 
     {% block messages %}
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/django/contrib/admin/templates/admin/change_form.html
+++ b/django/contrib/admin/templates/admin/change_form.html
@@ -1,6 +1,7 @@
 {% extends "admin/base_site.html" %}
 {% load i18n static admin_modify %}
 {% load url from future %}
+{% load admin_urls %}
 
 {% block extrahead %}{{ block.super }}
 {% url 'admin:jsi18n' as jsi18nurl %}
@@ -14,14 +15,15 @@
 
 {% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
 
-{% block breadcrumbs %}{% if not is_popup %}
-<div class="breadcrumbs">
-     <a href="../../../">{% trans "Home" %}</a> &rsaquo;
-     <a href="../../">{{ app_label|capfirst|escape }}</a> &rsaquo;
-     {% if has_change_permission %}<a href="../">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %} &rsaquo;
-     {% if add %}{% trans "Add" %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
+{% if not is_popup %}
+{% block breadcrumbs %}
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ app_label|capfirst|escape }}</a>
+&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 %}
+&rsaquo; {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
 </div>
-{% endif %}{% endblock %}
+{% endblock %}
+{% endif %}
 
 {% block content %}<div id="content-main">
 {% block object-tools %}
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/django/contrib/admin/templates/admin/change_list.html
+++ b/django/contrib/admin/templates/admin/change_list.html
@@ -1,6 +1,8 @@
 {% extends "admin/base_site.html" %}
 {% load i18n static admin_list %}
 {% load url from future %}
+{% load admin_urls %}
+
 {% block extrastyle %}
   {{ block.super }}
   <link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}" />
@@ -36,19 +38,13 @@
 {% block bodyclass %}change-list{% endblock %}
 
 {% if not is_popup %}
-  {% block breadcrumbs %}
-    <div class="breadcrumbs">
-      <a href="../../">
-        {% trans "Home" %}
-      </a>
-       &rsaquo;
-       <a href="../">
-         {{ app_label|capfirst }}
-      </a>
-      &rsaquo;
-      {{ cl.opts.verbose_name_plural|capfirst }}
-    </div>
-  {% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'admin:app_list' app_label=cl.opts.app_label %}">{{ app_label|capfirst|escape }}</a>
+&rsaquo; {{ cl.opts.verbose_name_plural|capfirst }}
+</div>
+{% endblock %}
 {% endif %}
 
 {% block coltype %}flex{% endblock %}
@@ -60,7 +56,7 @@
         <ul class="object-tools">
           {% block object-tools-items %}
             <li>
-              <a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">
+              <a href="{% model_url 'admin:%s_%s_add' cl.opts.app_label cl.opts.module_name %}{% if is_popup %}?_popup=1{% endif %}" class="addlink">
                 {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
               </a>
             </li>
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/django/contrib/admin/templates/admin/delete_confirmation.html
+++ b/django/contrib/admin/templates/admin/delete_confirmation.html
@@ -1,13 +1,15 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
+{% load admin_urls %}
 
 {% block breadcrumbs %}
 <div class="breadcrumbs">
-     <a href="../../../../">{% trans "Home" %}</a> &rsaquo;
-     <a href="../../../">{{ app_label|capfirst }}</a> &rsaquo; 
-     <a href="../../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
-     <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo;
-     {% trans 'Delete' %}
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ app_label|capfirst }}</a>
+&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}">{{ opts.verbose_name_plural|capfirst|escape }}</a>
+&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}{{ object.pk }}">{{ object|truncatewords:"18" }}</a>
+&rsaquo; {% trans 'Delete' %}
 </div>
 {% endblock %}
 
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/django/contrib/admin/templates/admin/delete_selected_confirmation.html
+++ b/django/contrib/admin/templates/admin/delete_selected_confirmation.html
@@ -1,12 +1,14 @@
 {% extends "admin/base_site.html" %}
 {% load i18n l10n %}
+{% load url from future %}
+{% load admin_urls %}
 
 {% block breadcrumbs %}
 <div class="breadcrumbs">
-     <a href="../../">{% trans "Home" %}</a> &rsaquo;
-     <a href="../">{{ app_label|capfirst }}</a> &rsaquo;
-     <a href="./">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
-     {% trans 'Delete multiple objects' %}
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'admin:app_list' app_label=app_label %}">{{ app_label|capfirst|escape }}</a>
+&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' app_label opts.module_name %}">{{ opts.verbose_name_plural|capfirst }}</a>
+&rsaquo; {% trans 'Delete multiple objects' %}
 </div>
 {% endblock %}
 
diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html
index 0f81a1a..b654329 100644
--- a/django/contrib/admin/templates/admin/index.html
+++ b/django/contrib/admin/templates/admin/index.html
@@ -26,7 +26,7 @@
             {% endif %}
 
             {% if model.perms.add %}
-                <td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
+                <td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
             {% else %}
                 <td>&nbsp;</td>
             {% endif %}
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/django/contrib/admin/templates/admin/invalid_setup.html
+++ b/django/contrib/admin/templates/admin/invalid_setup.html
@@ -1,7 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {{ title }}</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {{ title }}
+</div>
+{% endblock %}
 
 {% block content %}
 <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>
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/django/contrib/admin/templates/admin/object_history.html
+++ b/django/contrib/admin/templates/admin/object_history.html
@@ -1,13 +1,15 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
+{% load admin_urls %}
 
 {% block breadcrumbs %}
 <div class="breadcrumbs">
-    <a href="../../../../">{% trans 'Home' %}</a> &rsaquo; 
-    <a href="../../../">{{ app_label|capfirst }}</a> &rsaquo; 
-    <a href="../../">{{ module_name }}</a> &rsaquo; 
-    <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo; 
-    {% trans 'History' %}
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'admin:app_list' app_label=app_label %}">{{ app_label|capfirst|escape }}</a>
+&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}">{{ module_name }}</a>
+&rsaquo; <a href="{% model_url 'admin:%s_%s_changelist' opts.app_label opts.module_name %}{{ object.pk }}">{{ object|truncatewords:"18" }}</a>
+&rsaquo; {% trans 'History' %}
 </div>
 {% endblock %}
 
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/django/contrib/admin/templates/registration/logged_out.html
+++ b/django/contrib/admin/templates/registration/logged_out.html
@@ -1,12 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a></div>{% endblock %}
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="{% url 'admin:index' %}">{% trans 'Home' %}</a></div>{% endblock %}
 
 {% block content %}
 
 <p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
 
-<p><a href="../">{% trans 'Log in again' %}</a></p>
+<p><a href="{% url 'admin:index' %}">{% trans 'Log in again' %}</a></p>
 
 {% endblock %}
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/django/contrib/admin/templates/registration/password_change_done.html
+++ b/django/contrib/admin/templates/registration/password_change_done.html
@@ -1,8 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
 {% load url from future %}
-{% 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 %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
+{% 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 %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Password change' %}
+</div>
+{% endblock %}
 
 {% block title %}{% trans 'Password change successful' %}{% endblock %}
 
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/django/contrib/admin/templates/registration/password_change_form.html
+++ b/django/contrib/admin/templates/registration/password_change_form.html
@@ -2,8 +2,13 @@
 {% load i18n static %}
 {% load url from future %}
 {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
-{% 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 %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
+{% 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 %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Password change' %}
+</div>
+{% endblock %}
 
 {% block title %}{% trans 'Password change' %}{% endblock %}
 
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/django/contrib/admin/templates/registration/password_reset_complete.html
+++ b/django/contrib/admin/templates/registration/password_reset_complete.html
@@ -1,7 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Password reset' %}
+</div>
+{% endblock %}
 
 {% block title %}{% trans 'Password reset complete' %}{% endblock %}
 
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/django/contrib/admin/templates/registration/password_reset_confirm.html
+++ b/django/contrib/admin/templates/registration/password_reset_confirm.html
@@ -1,7 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset confirmation' %}</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Password reset confirmation' %}
+</div>
+{% endblock %}
 
 {% block title %}{% trans 'Password reset' %}{% endblock %}
 
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/django/contrib/admin/templates/registration/password_reset_done.html
+++ b/django/contrib/admin/templates/registration/password_reset_done.html
@@ -1,7 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Password reset' %}
+</div>
+{% endblock %}
 
 {% block title %}{% trans 'Password reset successful' %}{% endblock %}
 
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/django/contrib/admin/templates/registration/password_reset_form.html
+++ b/django/contrib/admin/templates/registration/password_reset_form.html
@@ -1,7 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Password reset' %}
+</div>
+{% endblock %}
 
 {% block title %}{% trans "Password reset" %}{% endblock %}
 
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
--- /dev/null
+++ b/django/contrib/admin/templatetags/admin_urls.py
@@ -0,0 +1,12 @@
+from django.core.urlresolvers import reverse, NoReverseMatch
+from django import template
+
+register = template.Library()
+
+def model_url(context, fmt_string, app_name, model_name):
+    try:
+        return reverse(fmt_string % (app_name, model_name),
+                current_app=context.current_app)
+    except NoReverseMatch:
+        return ''
+register.simple_tag(takes_context=True)(model_url)
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index bf48f16..15bccff 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -113,29 +113,40 @@ class ForeignKeyRawIdWidget(forms.TextInput):
     A Widget for displaying ForeignKeys in the "raw_id" interface rather than
     in a <select> box.
     """
-    def __init__(self, rel, attrs=None, using=None):
+    def __init__(self, rel, admin_site, attrs=None, using=None):
         self.rel = rel
         self.db = using
+        self.admin_site = admin_site
         super(ForeignKeyRawIdWidget, self).__init__(attrs)
 
     def render(self, name, value, attrs=None):
+        rel_to = self.rel.to
         if attrs is None:
             attrs = {}
-        related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower())
-        params = self.url_parameters()
-        if params:
-            url = u'?' + u'&amp;'.join([u'%s=%s' % (k, v) for k, v in params.items()])
-        else:
-            url = u''
-        if "class" not in attrs:
-            attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
-        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
-        # TODO: "id_" is hard-coded here. This should instead use the correct
-        # API to determine the ID dynamically.
-        output.append(u'<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> '
-                      % (related_url, url, name))
-        output.append(u'<img src="%s" width="16" height="16" alt="%s" /></a>'
-                      % (static('admin/img/selector-search.gif'), _('Lookup')))
+        extra = []
+        if rel_to in self.admin_site._registry: # If the related object has an admin interface:
+            try:
+                related_url = reverse('admin:%s_%s_changelist' %
+                                        (rel_to._meta.app_label,
+                                        rel_to._meta.module_name),
+                                        current_app=self.admin_site.name)
+            except NoReverseMatch:
+                raise
+
+            params = self.url_parameters()
+            if params:
+                url = u'?' + u'&amp;'.join([u'%s=%s' % (k, v) for k, v in params.items()])
+            else:
+                url = u''
+            if "class" not in attrs:
+                attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript code looks for this hook.
+            # TODO: "id_" is hard-coded here. This should instead use the correct
+            # API to determine the ID dynamically.
+            extra.append(u'<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> '
+                         % (related_url, url, name))
+            extra.append(u'<img src="%s" width="16" height="16" alt="%s" /></a>'
+                         % (static('admin/img/selector-search.gif'), _('Lookup')))
+        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] + extra
         if value:
             output.append(self.label_for_value(value))
         return mark_safe(u''.join(output))
@@ -229,14 +240,10 @@ class RelatedFieldWidgetWrapper(forms.Widget):
     def render(self, name, value, *args, **kwargs):
         rel_to = self.rel.to
         info = (rel_to._meta.app_label, rel_to._meta.object_name.lower())
-        try:
-            related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
-        except NoReverseMatch:
-            info = (self.admin_site.root_path, rel_to._meta.app_label, rel_to._meta.object_name.lower())
-            related_url = '%s%s/%s/add/' % info
         self.widget.choices = self.choices
         output = [self.widget.render(name, value, *args, **kwargs)]
         if self.can_add_related:
+            related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
             # TODO: "id_" is hard-coded here. This should instead use the correct
             # API to determine the ID dynamically.
             output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> '
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/django/contrib/admindocs/templates/admin_doc/bookmarklets.html
+++ b/django/contrib/admindocs/templates/admin_doc/bookmarklets.html
@@ -1,6 +1,14 @@
 {% extends "admin/base_site.html" %}
-
-{% block breadcrumbs %}{% load i18n %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> &rsaquo; <a href="../">{% trans "Documentation" %}</a> &rsaquo; {% trans "Bookmarklets" %}</div>{% endblock %}
+{% load i18n %}
+{% load url from future %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; {% trans 'Bookmarklets' %}
+</div>
+{% endblock %}
 {% block title %}{% trans "Documentation bookmarklets" %}{% endblock %}
 
 {% block content %}
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/django/contrib/admindocs/templates/admin_doc/index.html
+++ b/django/contrib/admindocs/templates/admin_doc/index.html
@@ -1,6 +1,13 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="{{ root_path }}">Home</a> &rsaquo; Documentation</div>{% endblock %}
+{% load url from future %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Documentation' %}</a>
+</div>
+{% endblock %}
 {% block title %}Documentation{% endblock %}
 
 {% block content %}
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/django/contrib/admindocs/templates/admin_doc/missing_docutils.html
+++ b/django/contrib/admindocs/templates/admin_doc/missing_docutils.html
@@ -1,6 +1,12 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> &rsaquo; Documentation</div>{% endblock %}
+{% load url from future %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; {% trans 'Documentation' %}</a>
+</div>
 {% block title %}Please install docutils{% endblock %}
 
 {% block content %}
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/django/contrib/admindocs/templates/admin_doc/model_detail.html
+++ b/django/contrib/admindocs/templates/admin_doc/model_detail.html
@@ -1,5 +1,7 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
+
 {% block extrahead %}
 {{ block.super }}
 <style type="text/css">
@@ -8,7 +10,14 @@
 </style>
 {% endblock %}
 
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Models</a> &rsaquo; {{ name }}</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-models-index' %}">{% trans 'Models' %}</a>
+&rsaquo; {{ name }}
+</div>
+{% endblock %}
 
 {% block title %}Model: {{ name }}{% endblock %}
 
@@ -41,6 +50,6 @@
 </table>
 </div>
 
-<p class="small"><a href="../">&lsaquo; Back to Models Documentation</a></p>
+<p class="small"><a href="{% url 'django-admindocs-models-index' %}">&lsaquo; Back to Models Documentation</a></p>
 </div>
 {% endblock %}
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/django/contrib/admindocs/templates/admin_doc/model_index.html
+++ b/django/contrib/admindocs/templates/admin_doc/model_index.html
@@ -1,7 +1,16 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
+
 {% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; Models</div>{% endblock %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; {% trans 'Models' %}
+</div>
+{% endblock %}
 
 {% block title %}Models{% endblock %}
 
@@ -19,7 +28,7 @@
 <table class="xfull">
 {% for model in group.list %}
 <tr>
-<th><a href="{{ model.app_label }}.{{ model.object_name.lower }}/">{{ model.object_name }}</a></th>
+<th><a href="{% url 'django-admindocs-models-detail' app_label=model.app_label model_name=model.object_name.lower %}">{{ model.object_name }}</a></th>
 </tr>
 {% endfor %}
 </table>
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/django/contrib/admindocs/templates/admin_doc/template_detail.html
+++ b/django/contrib/admindocs/templates/admin_doc/template_detail.html
@@ -1,6 +1,15 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; Templates &rsaquo; {{ name }}</div>{% endblock %}
+{% load url from future %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; {% trans 'Templates' %}
+&rsaquo; {{ name }}
+</div>
+{% endblock %}
 
 {% block title %}Template: {{ name }}{% endblock %}
 
@@ -17,5 +26,5 @@
     </ol>
 {% endfor %}
 
-<p class="small"><a href="../../">&lsaquo; Back to Documentation</a></p>
+<p class="small"><a href="{% url 'django-admindocs-docroot' %}">&lsaquo; Back to Documentation</a></p>
 {% endblock %}
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/django/contrib/admindocs/templates/admin_doc/template_filter_index.html
+++ b/django/contrib/admindocs/templates/admin_doc/template_filter_index.html
@@ -1,7 +1,15 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
+
 {% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; filters</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; {% trans 'Filters' %}
+</div>
+{% endblock %}
 {% block title %}Template filters{% endblock %}
 
 {% block content %}
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/django/contrib/admindocs/templates/admin_doc/template_tag_index.html
+++ b/django/contrib/admindocs/templates/admin_doc/template_tag_index.html
@@ -1,7 +1,15 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
+
 {% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; Tags</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; {% trans 'Tags' %}
+</div>
+{% endblock %}
 {% block title %}Template tags{% endblock %}
 
 {% block content %}
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/django/contrib/admindocs/templates/admin_doc/view_detail.html
+++ b/django/contrib/admindocs/templates/admin_doc/view_detail.html
@@ -1,6 +1,15 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Views</a> &rsaquo; {{ name }}</div>{% endblock %}
+{% load url from future %}
+
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-views-index' %}">{% trans 'Views' %}</a>
+&rsaquo; {{ name }}
+</div>
+{% endblock %}
 {% block title %}View: {{ name }}{% endblock %}
 
 {% block content %}
@@ -21,5 +30,5 @@
 <p>{{ meta.Templates }}</p>
 {% endif %}
 
-<p class="small"><a href="../">&lsaquo; Back to Views Documentation</a></p>
+<p class="small"><a href="{% url 'django-admindocs-views-index' %}">&lsaquo; Back to Views Documentation</a></p>
 {% endblock %}
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/django/contrib/admindocs/templates/admin_doc/view_index.html
+++ b/django/contrib/admindocs/templates/admin_doc/view_index.html
@@ -1,7 +1,15 @@
 {% extends "admin/base_site.html" %}
 {% load i18n %}
+{% load url from future %}
+
 {% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> &rsaquo; <a href="../">Documentation</a> &rsaquo; Views</div>{% endblock %}
+{% block breadcrumbs %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+&rsaquo; <a href="{% url 'django-admindocs-docroot' %}">{% trans 'Documentation' %}</a>
+&rsaquo; {% trans 'Views' %}
+</div>
+{% endblock %}
 {% block title %}Views{% endblock %}
 
 {% block content %}
@@ -29,8 +37,8 @@
 
 {% for view in site_views.list|dictsort:"url" %}
 {% ifchanged %}
-<h3><a href="{{ view.module }}.{{ view.name }}/">{{ view.url }}</a></h3>
-<p class="small quiet">View function: {{ view.module }}.{{ view.name }}</p>
+<h3><a href="{% url 'django-admindocs-views-detail' view=view.full_name %}">{{ view.url }}</a></h3>
+<p class="small quiet">View function: {{ view.full_name }}</p>
 <p>{{ view.title }}</p>
 <hr />
 {% endifchanged %}
diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py
index 079f7ab..d65c257 100644
--- a/django/contrib/admindocs/views.py
+++ b/django/contrib/admindocs/views.py
@@ -133,8 +133,7 @@ def view_index(request):
             site_obj = GenericSite()
         for (func, regex) in view_functions:
             views.append({
-                'name': getattr(func, '__name__', func.__class__.__name__),
-                'module': func.__module__,
+                'full_name': '%s.%s' % (func.__module__, getattr(func, '__name__', func.__class__.__name__)),
                 'site_id': settings_mod.SITE_ID,
                 'site': site_obj,
                 'url': simplify_regex(regex),
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
--- /dev/null
+++ b/tests/regressiontests/admin_custom_urls/__init__.py
@@ -0,0 +1 @@
+#
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
--- /dev/null
+++ b/tests/regressiontests/admin_custom_urls/fixtures/actions.json
@@ -0,0 +1,44 @@
+[
+  {
+    "pk": "delete", 
+    "model": "admin_custom_urls.action", 
+    "fields": {
+      "description": "Remove things."
+    }
+  }, 
+  {
+    "pk": "rename", 
+    "model": "admin_custom_urls.action", 
+    "fields": {
+      "description": "Gives things other names."
+    }
+  }, 
+  {
+    "pk": "add", 
+    "model": "admin_custom_urls.action", 
+    "fields": {
+      "description": "Add things."
+    }
+  }, 
+  {
+    "pk": "path/to/file/", 
+    "model": "admin_custom_urls.action", 
+    "fields": {
+      "description": "An action with '/' in its name."
+    }
+  }, 
+  {
+    "pk": "path/to/html/document.html", 
+    "model": "admin_custom_urls.action", 
+    "fields": {
+      "description": "An action with a name similar to a HTML doc path."
+    }
+  }, 
+  {
+    "pk": "javascript:alert('Hello world');\">Click here</a>", 
+    "model": "admin_custom_urls.action", 
+    "fields": {
+      "description": "An action with a name suspected of being a XSS attempt"
+    }
+  }
+]
\ No newline at end of file
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
--- /dev/null
+++ b/tests/regressiontests/admin_custom_urls/fixtures/users.json
@@ -0,0 +1,20 @@
+[
+  {
+    "pk": 100,
+    "model": "auth.user",
+    "fields": {
+      "username": "super",
+      "first_name": "Super",
+      "last_name": "User",
+      "is_active": true,
+      "is_superuser": true,
+      "is_staff": true,
+      "last_login": "2007-05-30 13:20:10",
+      "groups": [],
+      "user_permissions": [],
+      "password": "sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158",
+      "email": "super@example.com",
+      "date_joined": "2007-05-30 13:20:10"
+    }
+  }
+]
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
--- /dev/null
+++ b/tests/regressiontests/admin_custom_urls/models.py
@@ -0,0 +1,50 @@
+from functools import update_wrapper
+
+from django.contrib import admin
+from django.db import models
+
+
+class Action(models.Model):
+    name = models.CharField(max_length=50, primary_key=True)
+    description = models.CharField(max_length=70)
+
+    def __unicode__(self):
+        return self.name
+
+
+class ActionAdmin(admin.ModelAdmin):
+    """
+    A ModelAdmin for the Action model that changes the URL of the add_view
+    to '<app name>/<model name>/!add/'
+    The Action model has a CharField PK.
+    """
+
+    list_display = ('name', 'description')
+
+    def remove_url(self, name):
+        """
+        Remove all entries named 'name' from the ModelAdmin instance URL
+        patterns list
+        """
+        return filter(lambda e: e.name != name, super(ActionAdmin, self).get_urls())
+
+    def get_urls(self):
+        # Add the URL of our custom 'add_view' view to the front of the URLs
+        # list.  Remove the existing one(s) first
+        from django.conf.urls.defaults import patterns, url
+
+        def wrap(view):
+            def wrapper(*args, **kwargs):
+                return self.admin_site.admin_view(view)(*args, **kwargs)
+            return update_wrapper(wrapper, view)
+
+        info = self.model._meta.app_label, self.model._meta.module_name
+
+        view_name = '%s_%s_add' % info
+
+        return patterns('',
+            url(r'^!add/$', wrap(self.add_view), name=view_name),
+        ) + self.remove_url(view_name)
+
+
+admin.site.register(Action, ActionAdmin)
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
--- /dev/null
+++ b/tests/regressiontests/admin_custom_urls/tests.py
@@ -0,0 +1,72 @@
+from django.core.urlresolvers import reverse
+from django.template.response import TemplateResponse
+from django.test import TestCase
+
+from models import Action
+
+
+class AdminCustomUrlsTest(TestCase):
+    fixtures = ['users.json', 'actions.json']
+
+    def setUp(self):
+        self.client.login(username='super', password='secret')
+
+    def tearDown(self):
+        self.client.logout()
+
+    def testBasicAddGet(self):
+        """
+        A smoke test to ensure GET on the add_view works.
+        """
+        response = self.client.get('/custom_urls/admin/admin_custom_urls/action/!add/')
+        self.assertIsInstance(response, TemplateResponse)
+        self.assertEqual(response.status_code, 200)
+
+    def testAddWithGETArgs(self):
+        response = self.client.get('/custom_urls/admin/admin_custom_urls/action/!add/', {'name': 'My Action'})
+        self.assertEqual(response.status_code, 200)
+        self.assertTrue(
+            'value="My Action"' in response.content,
+            "Couldn't find an input with the right value in the response."
+        )
+
+    def testBasicAddPost(self):
+        """
+        A smoke test to ensure POST on add_view works.
+        """
+        post_data = {
+            '_popup': u'1',
+            "name": u'Action added through a popup',
+            "description": u"Description of added action",
+        }
+        response = self.client.post('/custom_urls/admin/admin_custom_urls/action/!add/', post_data)
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, 'dismissAddAnotherPopup')
+        self.assertContains(response, 'Action added through a popup')
+
+    def testAdminUrlsNoClash(self):
+        """
+        Test that some admin URLs work correctly. The model has a CharField
+        PK and the add_view URL has been customized.
+        """
+        # Should get the change_view for model instance with PK 'add', not show
+        # the add_view
+        response = self.client.get('/custom_urls/admin/admin_custom_urls/action/add/')
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, 'Change action')
+
+        # Ditto, but use reverse() to build the URL
+        path = reverse('admin:%s_action_change' % Action._meta.app_label,
+                args=('add',))
+        response = self.client.get(path)
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, 'Change action')
+
+        # Should correctly get the change_view for the model instance with the
+        # funny-looking PK
+        path = reverse('admin:%s_action_change' % Action._meta.app_label,
+                args=("path/to/html/document.html",))
+        response = self.client.get(path)
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, 'Change action')
+        self.assertContains(response, 'value="path/to/html/document.html"')
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
--- /dev/null
+++ b/tests/regressiontests/admin_custom_urls/urls.py
@@ -0,0 +1,7 @@
+from django.conf.urls.defaults import *
+from django.contrib import admin
+
+urlpatterns = patterns('',
+    (r'^admin/', include(admin.site.urls)),
+)
+
diff --git a/tests/regressiontests/admin_inlines/models.py b/tests/regressiontests/admin_inlines/models.py
index ee0abd1..9f7d080 100644
--- a/tests/regressiontests/admin_inlines/models.py
+++ b/tests/regressiontests/admin_inlines/models.py
@@ -44,6 +44,7 @@ class BookInline(admin.TabularInline):
 class AuthorAdmin(admin.ModelAdmin):
     inlines = [BookInline]
 
+admin.site.register(Book)
 admin.site.register(Author, AuthorAdmin)
 
 class Holder(models.Model):
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 7128f04..85fb66c 100644
--- a/tests/regressiontests/admin_views/tests.py
+++ b/tests/regressiontests/admin_views/tests.py
@@ -585,7 +585,7 @@ class SaveAsTests(TestCase):
         self.assertTrue(response.context['save_as'])
         post_data = {'_saveasnew':'', 'name':'John M', 'gender':3, 'alive':'checked'}
         response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data)
-        self.assertEqual(response.context['form_url'], '../add/')
+        self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/')
 
 class CustomModelAdminTest(AdminViewBasicTest):
     urlbit = "admin2"
@@ -830,7 +830,7 @@ class AdminViewPermissionsTest(TestCase):
         self.client.post('/test_admin/admin/', self.adduser_login)
         addpage = self.client.get('/test_admin/admin/admin_views/article/add/')
         self.assertEqual(addpage.status_code, 200)
-        change_list_link = '<a href="../">Articles</a> &rsaquo;'
+        change_list_link = '&rsaquo; <a href="/test_admin/admin/admin_views/article/">Articles</a>'
         self.assertFalse(change_list_link in addpage.content,
                     'User restricted to add permission is given link to change list view in breadcrumbs.')
         post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py
index 3cdb017..ac3baa0 100644
--- a/tests/regressiontests/admin_widgets/tests.py
+++ b/tests/regressiontests/admin_widgets/tests.py
@@ -255,10 +255,10 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase):
         )
         rel = models.Album._meta.get_field('band').rel
 
-        w = ForeignKeyRawIdWidget(rel)
+        w = ForeignKeyRawIdWidget(rel, admin.site)
         self.assertEqual(
             conditional_escape(w.render('test', band.pk, attrs={})),
-            '<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),
+            '<input type="text" name="test" value="%(bandpk)s" />&nbsp;<strong>Linkin Park</strong>' % {"bandpk": band.pk}
         )
 
     def test_relations_to_non_primary_key(self):
@@ -270,17 +270,17 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase):
             barcode=87, name='Core', parent=apple
         )
         rel = models.Inventory._meta.get_field('parent').rel
-        w = ForeignKeyRawIdWidget(rel)
+        w = ForeignKeyRawIdWidget(rel, admin.site)
         self.assertEqual(
             w.render('test', core.parent_id, attrs={}),
-            '<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(),
+            '<input type="text" name="test" value="86" />&nbsp;<strong>Apple</strong>',
         )
 
 
     def test_proper_manager_for_label_lookup(self):
         # see #9258
         rel = models.Inventory._meta.get_field('parent').rel
-        w = ForeignKeyRawIdWidget(rel)
+        w = ForeignKeyRawIdWidget(rel, admin.site)
 
         hidden = models.Inventory.objects.create(
             barcode=93, name='Hidden', hidden=True
@@ -290,7 +290,7 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase):
         )
         self.assertEqual(
             w.render('test', child_of_hidden.parent_id, attrs={}),
-            '<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(),
+            '<input type="text" name="test" value="93" />&nbsp;<strong>Hidden</strong>',
         )
 
 
@@ -306,15 +306,15 @@ class ManyToManyRawIdWidgetTest(DjangoTestCase):
         band.members.add(m1, m2)
         rel = models.Band._meta.get_field('members').rel
 
-        w = ManyToManyRawIdWidget(rel)
+        w = ManyToManyRawIdWidget(rel, admin.site)
         self.assertEqual(
             conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})),
-            '<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),
+            '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" />' % {"m1pk": m1.pk, "m2pk": m2.pk},
         )
 
         self.assertEqual(
             conditional_escape(w.render('test', [m1.pk])),
-            '<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),
+            '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" />' % {"m1pk": m1.pk},
         )
 
         self.assertEqual(w._has_changed(None, None), False)
diff --git a/tests/regressiontests/admin_widgets/widgetadmin.py b/tests/regressiontests/admin_widgets/widgetadmin.py
index 6f15d92..9082f8a 100644
--- a/tests/regressiontests/admin_widgets/widgetadmin.py
+++ b/tests/regressiontests/admin_widgets/widgetadmin.py
@@ -28,3 +28,7 @@ site.register(models.User)
 site.register(models.Car, CarAdmin)
 site.register(models.CarTire, CarTireAdmin)
 site.register(models.Event, EventAdmin)
+
+site.register(models.Inventory)
+site.register(models.Member)
+site.register(models.Band)
diff --git a/tests/urls.py b/tests/urls.py
index b3f719d..929a913 100644
--- a/tests/urls.py
+++ b/tests/urls.py
@@ -29,4 +29,7 @@ urlpatterns = patterns('',
     # admin widget tests
     (r'widget_admin/', include('regressiontests.admin_widgets.urls')),
 
+    # admin custom URL tests
+    (r'^custom_urls/', include('regressiontests.admin_custom_urls.urls')),
+
 )
