diff --git a/django/contrib/admin/static/admin/css/forms.css b/django/contrib/admin/static/admin/css/forms.css
index d088d8db42..199ab3475e 100644
--- a/django/contrib/admin/static/admin/css/forms.css
+++ b/django/contrib/admin/static/admin/css/forms.css
@@ -374,3 +374,22 @@ body.popup .submit-row {
.empty-form {
display: none;
}
+
+/* RELATED FIELD ADD ONE / LOOKUP */
+
+.add-another, .related-lookup {
+ margin-left: 5px;
+ display: inline-block;
+}
+
+.add-another {
+ width: 10px;
+ height: 10px;
+ background-image: url(../img/icon_addlink.gif);
+}
+
+.related-lookup {
+ width: 16px;
+ height: 16px;
+ background-image: url(../img/selector-search.gif);
+}
diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
index 0d7ca41d94..01580fd833 100644
--- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
+++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
@@ -27,20 +27,24 @@ function windowname_to_id(text) {
return text;
}
-function showRelatedObjectLookupPopup(triggeringLink) {
- var name = triggeringLink.id.replace(/^lookup_/, '');
+function showAdminPopup(triggeringLink, name_regexp) {
+ var name = triggeringLink.id.replace(name_regexp, '');
name = id_to_windowname(name);
- var href;
- if (triggeringLink.href.search(/\?/) >= 0) {
- href = triggeringLink.href + '&_popup=1';
+ var href = triggeringLink.href;
+ if (href.indexOf('?') == -1) {
+ href += '?_popup=1';
} else {
- href = triggeringLink.href + '?_popup=1';
+ href += '&_popup=1';
}
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
return false;
}
+function showRelatedObjectLookupPopup(triggeringLink) {
+ return showAdminPopup(triggeringLink, /^lookup_/);
+}
+
function dismissRelatedLookupPopup(win, chosenId) {
var name = windowname_to_id(win.name);
var elem = document.getElementById(name);
@@ -53,17 +57,7 @@ function dismissRelatedLookupPopup(win, chosenId) {
}
function showAddAnotherPopup(triggeringLink) {
- var name = triggeringLink.id.replace(/^add_/, '');
- name = id_to_windowname(name);
- var href = triggeringLink.href;
- if (href.indexOf('?') == -1) {
- href += '?_popup=1';
- } else {
- href += '&_popup=1';
- }
- var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
- win.focus();
- return false;
+ return showAdminPopup(triggeringLink, /^add_/);
}
function dismissAddAnotherPopup(win, newId, newRepr) {
diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
index d68f71ebd3..0fc4a25138 100644
--- a/django/contrib/admin/templates/admin/change_form.html
+++ b/django/contrib/admin/templates/admin/change_form.html
@@ -67,15 +67,25 @@
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
-{% if adminform and add %}
+{% block admin_change_form_document_ready %}
-{% endif %}
+{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index 68575794f6..3b14087176 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -170,10 +170,8 @@ class ForeignKeyRawIdWidget(forms.TextInput):
attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript code looks for this hook.
# TODO: "lookup_id_" is hard-coded here. This should instead use
# the correct API to determine the ID dynamically.
- extra.append(' ' %
- (related_url, url, name))
- extra.append('' %
- (static('admin/img/selector-search.gif'), _('Lookup')))
+ extra.append('' %
+ (related_url, url, name, _('Lookup')))
output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] + extra
if value:
output.append(self.label_for_value(value))
@@ -265,19 +263,17 @@ class RelatedFieldWidgetWrapper(forms.Widget):
def render(self, name, value, *args, **kwargs):
from django.contrib.admin.views.main import TO_FIELD_VAR
- rel_to = self.rel.to
- info = (rel_to._meta.app_label, rel_to._meta.model_name)
self.widget.choices = self.choices
output = [self.widget.render(name, value, *args, **kwargs)]
if self.can_add_related:
+ rel_to = self.rel.to
+ info = (rel_to._meta.app_label, rel_to._meta.model_name)
related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
url_params = '?%s=%s' % (TO_FIELD_VAR, self.rel.get_related_field().name)
# TODO: "add_id_" is hard-coded here. This should instead use the
# correct API to determine the ID dynamically.
- output.append(' '
- % (related_url, url_params, name))
- output.append(''
- % (static('admin/img/icon_addlink.gif'), _('Add Another')))
+ output.append(''
+ % (related_url, url_params, name, _('Add Another')))
return mark_safe(''.join(output))
def build_attrs(self, extra_attrs=None, **kwargs):
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index e75b86ac4b..f1d2dab520 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -3990,7 +3990,7 @@ class UserAdminTest(TestCase):
response = self.client.get('/test_admin/admin/admin_views/album/add/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, '/test_admin/admin/auth/user/add')
- self.assertContains(response, 'class="add-another" id="add_id_owner" onclick="return showAddAnotherPopup(this);"')
+ self.assertContains(response, 'class="add-another" id="add_id_owner"')
response = self.client.get('/test_admin/admin/auth/user/add/?_popup=1')
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, 'name="_continue"')
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 35fc04e9f8..39f89f6a40 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -386,8 +386,11 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase):
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', band.pk, attrs={}),
- ' Linkin Park' % dict(admin_static_prefix(), bandpk=band.pk)
+ w.render('test', band.pk, attrs={}), (
+ ''
+ ''
+ ' Linkin Park'
+ ) % {'bandpk': band.pk}
)
def test_relations_to_non_primary_key(self):
@@ -401,8 +404,11 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase):
rel = models.Inventory._meta.get_field('parent').rel
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', core.parent_id, attrs={}),
- ' Apple' % admin_static_prefix()
+ w.render('test', core.parent_id, attrs={}), (
+ ''
+ ''
+ ' Apple'
+ )
)
def test_fk_related_model_not_in_admin(self):
@@ -443,8 +449,11 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase):
barcode=94, name='Child of hidden', parent=hidden
)
self.assertHTMLEqual(
- w.render('test', child_of_hidden.parent_id, attrs={}),
- ' Hidden' % admin_static_prefix()
+ w.render('test', child_of_hidden.parent_id, attrs={}), (
+ ''
+ ''
+ ' Hidden'
+ )
)
@@ -461,13 +470,17 @@ class ManyToManyRawIdWidgetTest(DjangoTestCase):
w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', [m1.pk, m2.pk], attrs={}),
- ' ' % dict(admin_static_prefix(), m1pk=m1.pk, m2pk=m2.pk)
+ w.render('test', [m1.pk, m2.pk], attrs={}), (
+ ''
+ ''
+ ) % dict(m1pk=m1.pk, m2pk=m2.pk)
)
self.assertHTMLEqual(
- w.render('test', [m1.pk]),
- ' ' % dict(admin_static_prefix(), m1pk=m1.pk)
+ w.render('test', [m1.pk]), (
+ ''
+ ''
+ ) % dict(m1pk=m1.pk)
)
def test_m2m_related_model_not_in_admin(self):