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 c603210..434d06c 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))
@@ -701,7 +704,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
@@ -744,9 +746,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):
@@ -755,11 +760,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()
@@ -773,19 +781,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):
"""
@@ -940,7 +957,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 {})
@@ -962,7 +978,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 = []
@@ -1034,7 +1052,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 {})
@@ -1176,7 +1193,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,
@@ -1223,8 +1239,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)
@@ -1241,7 +1260,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 {})
@@ -1269,8 +1287,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..45f8399 100644
--- a/django/contrib/admin/templates/admin/500.html
+++ b/django/contrib/admin/templates/admin/500.html
@@ -1,7 +1,8 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
-{% block breadcrumbs %}
{% endblock %}
+{% block crumbs %}› {% trans "Server error" %}{% 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..7625e72 100644
--- a/django/contrib/admin/templates/admin/app_index.html
+++ b/django/contrib/admin/templates/admin/app_index.html
@@ -1,15 +1,14 @@
-{% extends "admin/index.html" %}
-{% load i18n %}
+{% extends "admin/index.html" %}
+{% load i18n %}
+{% load url from future %}
{% if not is_popup %}
-
-{% block breadcrumbs %}
-
-{% trans "Home" %} ›
-{% for app in app_list %}
-{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
-{% endfor %}
{% endblock %}
-
-{% endif %}
-
-{% block sidebar %}{% endblock %}
\ No newline at end of file
+{% block crumbs %}
+ ›
+ {% for app in app_list %}
+ {% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
+ {% endfor %}
+{% endblock %}
+{% endif %}
+
+{% 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 5a2036d..0c32513 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,21 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_modify adminmedia %}
{% load url from future %}
+{% load admin_urls %}
{% block extrahead %}{{ block.super }}
{% url 'admin:jsi18n' as jsi18nurl %}
{% endblock %}
{% block extrastyle %}{{ block.super }} {% endblock %}
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
-{% block breadcrumbs %}{% if not is_popup %}
-
-{% endif %}{% endblock %}
+{% if not is_popup %}
+ {% block crumbs %}
+ {{ opts.app_label|capfirst|escape }} ›
+ {{ opts.verbose_name_plural|capfirst }} ›
+ {{ original|truncatewords:"18" }} ›
+ {% trans 'Change password' %}
+ {% endblock %}
+{% endif %}
{% block content %}
- {% block breadcrumbs %}{% endblock %}
+ {% block breadcrumbs %}
+
+
{% trans 'Home' %}
+ {% block crumbs %}
+ {% if title %} › {{ title }}{% endif %}
+ {% endblock %}
+
+ {% 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 b32f76d..325c5b3 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 admin_modify adminmedia %}
{% load url from future %}
+{% load admin_urls %}
{% block extrahead %}{{ block.super }}
{% url 'admin:jsi18n' as jsi18nurl %}
@@ -14,14 +15,13 @@
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
-{% block breadcrumbs %}{% if not is_popup %}
-
-{% endif %}{% endblock %}
+{% if not is_popup %}
+ {% block crumbs %}
+ › {{ app_label|capfirst|escape }}
+ › {% if has_change_permission %}{{ opts.verbose_name_plural|capfirst }} {% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
+ › {% if add %}{% trans 'Add' %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
+ {% endblock %}
+{% endif %}
{% block content %}
{% block object-tools %}
diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html
index 2e7c8e3..96c3729 100644
--- a/django/contrib/admin/templates/admin/change_list.html
+++ b/django/contrib/admin/templates/admin/change_list.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load adminmedia admin_list i18n %}
{% load url from future %}
+{% load admin_urls %}
{% block extrastyle %}
{{ block.super }}
@@ -36,19 +37,10 @@
{% block bodyclass %}change-list{% endblock %}
{% if not is_popup %}
- {% block breadcrumbs %}
-
- {% endblock %}
+ {% block crumbs %}
+ ›
{{ app_label|capfirst|escape }}
+ › {{ cl.opts.verbose_name_plural|capfirst }}
+ {% endblock %}
{% endif %}
{% block coltype %}flex{% endblock %}
@@ -60,7 +52,7 @@
{% block object-tools-items %}
-
+
{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html
index 9187b60..4a0169f 100644
--- a/django/contrib/admin/templates/admin/delete_confirmation.html
+++ b/django/contrib/admin/templates/admin/delete_confirmation.html
@@ -1,14 +1,13 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
+{% load admin_urls %}
-{% block breadcrumbs %}
-
+{% block crumbs %}
+ › {{ app_label|capfirst }}
+ › {{ opts.verbose_name_plural|capfirst|escape }}
+ › {{ object|truncatewords:"18" }}
+ › {% trans 'Delete' %}
{% endblock %}
{% block content %}
diff --git a/django/contrib/admin/templates/admin/delete_selected_confirmation.html b/django/contrib/admin/templates/admin/delete_selected_confirmation.html
index cedf14e..c52d0ff 100644
--- a/django/contrib/admin/templates/admin/delete_selected_confirmation.html
+++ b/django/contrib/admin/templates/admin/delete_selected_confirmation.html
@@ -1,13 +1,12 @@
{% extends "admin/base_site.html" %}
{% load i18n l10n %}
+{% load url from future %}
+{% load admin_urls %}
-{% block breadcrumbs %}
-
+{% block crumbs %}
+ › {{ app_label|capfirst|escape }}
+ › {{ opts.verbose_name_plural|capfirst }}
+ › {% trans 'Delete multiple objects' %}
{% endblock %}
{% block content %}
diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html
index d392f07..27b6145 100644
--- a/django/contrib/admin/templates/admin/index.html
+++ b/django/contrib/admin/templates/admin/index.html
@@ -7,7 +7,7 @@
{% block bodyclass %}dashboard{% endblock %}
-{% block breadcrumbs %}{% endblock %}
+{% block crumbs %}{% endblock %}
{% block content %}
@@ -26,7 +26,7 @@
{% endif %}
{% if model.perms.add %}
-
{% trans 'Add' %}
+
{% trans 'Add' %}
{% else %}
{% endif %}
diff --git a/django/contrib/admin/templates/admin/invalid_setup.html b/django/contrib/admin/templates/admin/invalid_setup.html
index f09b316..3696c9e 100644
--- a/django/contrib/admin/templates/admin/invalid_setup.html
+++ b/django/contrib/admin/templates/admin/invalid_setup.html
@@ -1,7 +1,10 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
-{% block breadcrumbs %}
{% endblock %}
+{% block crumbs %}
+ › {{ title }}
+{% endblock %}
{% block content %}
{% 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." %}
diff --git a/django/contrib/admin/templates/admin/object_history.html b/django/contrib/admin/templates/admin/object_history.html
index 5ae7847..37e72ec 100644
--- a/django/contrib/admin/templates/admin/object_history.html
+++ b/django/contrib/admin/templates/admin/object_history.html
@@ -1,14 +1,14 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
+{% load admin_urls %}
-{% block breadcrumbs %}
-
+{% block crumbs %}
+ {{ block.super }}
+ ›
{{ app_label|capfirst|escape }}
+ ›
{{ module_name }}
+ ›
{{ object|truncatewords:"18" }}
+ › {% trans 'History' %}
{% endblock %}
{% block content %}
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 %}
{% endblock %}
+{% block breadcrumbs %}
{% endblock %}
{% block content %}
{% trans "Thanks for spending some quality time with the Web site today." %}
-
{% trans 'Log in again' %}
+
{% trans 'Log in again' %}
{% 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..ab0aefe 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 %}
{% trans 'Documentation' %} / {% endif %}{% trans 'Change password' %} /
{% trans 'Log out' %} {% endblock %}
-{% block breadcrumbs %}
{% endblock %}
+{% block userlinks %}{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}
{% trans 'Documentation' %} / {% endif %}{% trans 'Change password' %} /
{% trans 'Log out' %} {% endblock %}
+{% block breadcrumbs %}
+
+{% 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 d313a79..949f43d 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 adminmedia %}
{% load url from future %}
{% block extrastyle %}{{ block.super }}
{% endblock %}
-{% block userlinks %}{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}
{% trans 'Documentation' %} / {% endif %} {% trans 'Change password' %} /
{% trans 'Log out' %} {% endblock %}
-{% block breadcrumbs %}
{% endblock %}
+{% block userlinks %}{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}
{% trans 'Documentation' %} / {% endif %} {% trans 'Change password' %} /
{% trans 'Log out' %} {% endblock %}
+{% block breadcrumbs %}
+
+{% 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..437bbf4 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 %}
{% endblock %}
+{% block breadcrumbs %}
+
+{% 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 546ae0f..4bd254c 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 %}
{% endblock %}
+{% block breadcrumbs %}
+
+{% 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..86de493 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 %}
{% endblock %}
+{% block breadcrumbs %}
+
+{% 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 575e237..101e8fb 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 %}
{% endblock %}
+{% block breadcrumbs %}
+
+{% 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 957f94f..c55a690 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -115,28 +115,39 @@ class ForeignKeyRawIdWidget(forms.TextInput):
A Widget for displaying ForeignKeys in the "raw_id" interface rather than
in a
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'&'.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' ' % \
- (related_url, url, name))
- output.append(u' ' % (settings.ADMIN_MEDIA_PREFIX, _('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'&'.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' ' % \
+ (related_url, url, name))
+ extra.append(u' ' % (settings.ADMIN_MEDIA_PREFIX, _('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))
@@ -230,14 +241,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' ' % \
diff --git a/django/contrib/admindocs/templates/admin_doc/bookmarklets.html b/django/contrib/admindocs/templates/admin_doc/bookmarklets.html
index 6447529..9f1993f 100644
--- a/django/contrib/admindocs/templates/admin_doc/bookmarklets.html
+++ b/django/contrib/admindocs/templates/admin_doc/bookmarklets.html
@@ -1,6 +1,8 @@
{% extends "admin/base_site.html" %}
+{% load i18n %}
+{% load url from future %}
-{% block breadcrumbs %}{% load i18n %}{% endblock %}
+{% block crumbs %}› {% trans "Documentation" %} › {% trans "Bookmarklets" %}{% 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..fab0567 100644
--- a/django/contrib/admindocs/templates/admin_doc/index.html
+++ b/django/contrib/admindocs/templates/admin_doc/index.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
-{% block breadcrumbs %}{% endblock %}
+
+{% block crumbs %}› Documentation{% 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..a07aaf6 100644
--- a/django/contrib/admindocs/templates/admin_doc/missing_docutils.html
+++ b/django/contrib/admindocs/templates/admin_doc/missing_docutils.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
-{% block breadcrumbs %}{% endblock %}
+
+{% block crumbs %}› Documentation{% endblock %}
{% 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..078fa5e 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 }}
{% endblock %}
-{% block breadcrumbs %}{% endblock %}
+{% block crumbs %}› Documentation › Models › {{ name }}{% endblock %}
{% block title %}Model: {{ name }}{% endblock %}
@@ -41,6 +43,6 @@
-‹ Back to Models Documentation
+‹ Back to Models Documentation
{% 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..5fd235e 100644
--- a/django/contrib/admindocs/templates/admin_doc/model_index.html
+++ b/django/contrib/admindocs/templates/admin_doc/model_index.html
@@ -1,7 +1,9 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
+
{% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}{% endblock %}
+{% block crumbs %}› Documentation › Models{% endblock %}
{% block title %}Models{% endblock %}
@@ -19,7 +21,7 @@
diff --git a/django/contrib/admindocs/templates/admin_doc/template_detail.html b/django/contrib/admindocs/templates/admin_doc/template_detail.html
index c04dedc..8594329 100644
--- a/django/contrib/admindocs/templates/admin_doc/template_detail.html
+++ b/django/contrib/admindocs/templates/admin_doc/template_detail.html
@@ -1,6 +1,8 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
-{% block breadcrumbs %}{% endblock %}
+{% load url from future %}
+
+{% block crumbs %}› Documentation › Templates › {{ name }}{% endblock %}
{% block title %}Template: {{ name }}{% endblock %}
@@ -17,5 +19,5 @@
{% endfor %}
-‹ Back to Documentation
+‹ Back to Documentation
{% 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..5f1021f 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,9 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
+
{% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}{% endblock %}
+{% block crumbs %}› Documentation › filters{% 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..7cda8d3 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,9 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
+
{% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}{% endblock %}
+{% block crumbs %}› Documentation › Tags{% 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..178ba41 100644
--- a/django/contrib/admindocs/templates/admin_doc/view_detail.html
+++ b/django/contrib/admindocs/templates/admin_doc/view_detail.html
@@ -1,6 +1,8 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
-{% block breadcrumbs %}{% endblock %}
+{% load url from future %}
+
+{% block crumbs %}› Documentation › Views › {{ name }}{% endblock %}
{% block title %}View: {{ name }}{% endblock %}
{% block content %}
@@ -21,5 +23,5 @@
{{ meta.Templates }}
{% endif %}
-‹ Back to Views Documentation
+‹ Back to Views Documentation
{% 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..cfe3e27 100644
--- a/django/contrib/admindocs/templates/admin_doc/view_index.html
+++ b/django/contrib/admindocs/templates/admin_doc/view_index.html
@@ -1,7 +1,9 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
+{% load url from future %}
+
{% block coltype %}colSM{% endblock %}
-{% block breadcrumbs %}{% endblock %}
+{% block crumbs %}› Documentation › Views{% endblock %}
{% block title %}Views{% endblock %}
{% block content %}
@@ -29,8 +31,8 @@
{% for view in site_views.list|dictsort:"url" %}
{% ifchanged %}
-
-View function: {{ view.module }}.{{ view.name }}
+
+View function: {{ view.full_name }}
{{ view.title }}
{% endifchanged %}
diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py
index 319b489..f79bdf8 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..e69de29
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",
+ "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 '//!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/models.py b/tests/regressiontests/admin_views/models.py
index 854fb60..08483e0 100644
--- a/tests/regressiontests/admin_views/models.py
+++ b/tests/regressiontests/admin_views/models.py
@@ -779,7 +779,6 @@ class CoverLetterAdmin(admin.ModelAdmin):
"""
def queryset(self, request):
- #return super(CoverLetterAdmin, self).queryset(request).only('author')
return super(CoverLetterAdmin, self).queryset(request).defer('date_written')
class Story(models.Model):
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 7c6cdd4..ea94da9 100644
--- a/tests/regressiontests/admin_views/tests.py
+++ b/tests/regressiontests/admin_views/tests.py
@@ -473,7 +473,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"
@@ -718,7 +718,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 = 'Articles ›'
+ change_list_link = '› Articles '
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 8f7a36c..5b49b02 100644
--- a/tests/regressiontests/admin_widgets/tests.py
+++ b/tests/regressiontests/admin_widgets/tests.py
@@ -252,10 +252,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={})),
- ' Linkin Park ' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX, "bandpk": band.pk},
+ ' Linkin Park ' % {"bandpk": band.pk}
)
def test_relations_to_non_primary_key(self):
@@ -267,17 +267,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={}),
- ' Apple ' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX},
+ ' Apple ',
)
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
@@ -287,7 +287,7 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase):
)
self.assertEqual(
w.render('test', child_of_hidden.parent_id, attrs={}),
- ' Hidden ' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX},
+ ' Hidden ',
)
@@ -303,15 +303,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={})),
- ' ' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX, "m1pk": m1.pk, "m2pk": m2.pk},
+ ' ' % {"m1pk": m1.pk, "m2pk": m2.pk},
)
self.assertEqual(
conditional_escape(w.render('test', [m1.pk])),
- ' ' % {"ADMIN_MEDIA_PREFIX": settings.ADMIN_MEDIA_PREFIX, "m1pk": m1.pk},
+ ' ' % {"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')),
+
)