diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
index 04a3492..98efe5a 100644
--- a/django/contrib/admin/helpers.py
+++ b/django/contrib/admin/helpers.py
@@ -1,4 +1,5 @@
from django import forms
+from django.core.urlresolvers import reverse
from django.contrib.admin.util import (flatten_fieldsets, lookup_field,
display_for_field, label_for_field, help_text_for_field)
from django.contrib.admin.templatetags.admin_static import static
@@ -189,6 +190,7 @@ class AdminReadonlyField(object):
result_repr = display_for_field(value, f)
return conditional_escape(result_repr)
+
class InlineAdminFormSet(object):
"""
A wrapper around an inline formset for use in the admin system.
@@ -251,9 +253,16 @@ class InlineAdminForm(AdminForm):
self.formset = formset
self.model_admin = model_admin
self.original = original
+ self.admin_url = None
if original is not None:
self.original_content_type_id = ContentType.objects.get_for_model(original).pk
- self.show_url = original and hasattr(original, 'get_absolute_url')
+ self.show_url = hasattr(original, 'get_absolute_url')
+ if (model_admin is not None and
+ original.__class__ in model_admin.admin_site._registry):
+ info = (original._meta.app_label, original._meta.object_name.lower())
+ self.admin_url = reverse('admin:%s_%s_change' % info, args=(original.pk,),
+ current_app=model_admin.admin_site.name)
+
super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields,
readonly_fields, model_admin)
diff --git a/django/contrib/admin/static/admin/js/actions.js b/django/contrib/admin/static/admin/js/actions.js
index 94aa6db..80d2d91 100644
--- a/django/contrib/admin/static/admin/js/actions.js
+++ b/django/contrib/admin/static/admin/js/actions.js
@@ -136,4 +136,30 @@
allToggle: "#action-toggle",
selectedClass: "selected"
}
+
+ $(function(){
+ /* Change the edit link next to foreign key selects
+ according to the selected value */
+ $("a.change-related").click(function(e){
+ e.preventDefault();
+ window.open($(this).attr("href"));
+ });
+ $("a.change-related").each(
+ function(i, el){
+ var elem = $(el),
+ defaultHref = elem.attr("href"),
+ selectId = elem.attr("id").split("_").slice(1).join("_");
+ $("#"+selectId).change(function(){
+ var val = $(this).val();
+ if (val === ""){
+ elem.hide();
+ return;
+ }
+ elem.show();
+ var newHref = defaultHref.replace(/\/\d+\/$/, "/" + val + "/");
+ elem.attr("href", newHref);
+ });
+ }
+ );
+ });
})(django.jQuery);
diff --git a/django/contrib/admin/static/admin/js/actions.min.js b/django/contrib/admin/static/admin/js/actions.min.js
index 21f00cd..5689fcc 100644
--- a/django/contrib/admin/static/admin/js/actions.min.js
+++ b/django/contrib/admin/static/admin/js/actions.min.js
@@ -1,7 +1,7 @@
-(function(a){a.fn.actions=function(h){var b=a.extend({},a.fn.actions.defaults,h),e=a(this),f=false;checker=function(c){c?showQuestion():reset();a(e).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(e).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},true));a(b.allToggle).attr("checked",function(){if(c==e.length){value=true;showQuestion()}else{value=
-false;clearAcross()}return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};
-a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();a(b.acrossInput).val()==1&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",false);clearAcross();checker(0);
-updateCounter()});lastChecked=null;a(e).click(function(c){if(!c)c=window.event;var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&c.shiftKey==true){var g=false;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(e).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))g=g?false:true;g&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,
-d.checked);lastChecked=d;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){f=true});a('form#changelist-form button[name="index"]').click(function(){if(f)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var c=false;a("div.actions select option:selected").each(function(){if(a(this).val())c=
-true});if(c)return f?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",
-acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
+(function(a){a.fn.actions=function(g){var b=a.extend({},a.fn.actions.defaults,g),d=a(this),e=!1;checker=function(c){c?showQuestion():reset();a(d).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(d).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).attr("checked",function(){c==d.length?(value=!0,showQuestion()):(value=
+!1,clearAcross());return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};
+a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();a(b.acrossInput).val()==1&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",!1);clearAcross();checker(0);
+updateCounter()});lastChecked=null;a(d).click(function(c){if(!c)c=window.event;var f=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(f)&&c.shiftKey==!0){var e=!1;a(lastChecked).attr("checked",f.checked).parent().parent().toggleClass(b.selectedClass,f.checked);a(d).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(f))e=e?!1:!0;e&&a(this).attr("checked",f.checked).parent().parent().toggleClass(b.selectedClass,f.checked)})}a(f).parent().parent().toggleClass(b.selectedClass,
+f.checked);lastChecked=f;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var b=!1;a("div.actions select option:selected").each(function(){a(this).val()&&(b=!0)});
+if(b)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",
+acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"};a(function(){a("a.change-related").click(function(g){g.preventDefault();window.open(a(this).attr("href"))});a("a.change-related").each(function(g,b){var d=a(b),e=d.attr("href"),c=d.attr("id").split("_").slice(1).join("_");a("#"+c).change(function(){var b=a(this).val();b===""?d.hide():(d.show(),b=e.replace(/\/\d+\/$/,"/"+b+"/"),d.attr("href",b))})})})})(django.jQuery);
diff --git a/django/contrib/admin/templates/admin/edit_inline/stacked.html b/django/contrib/admin/templates/admin/edit_inline/stacked.html
index 476e261..cf6723b 100644
--- a/django/contrib/admin/templates/admin/edit_inline/stacked.html
+++ b/django/contrib/admin/templates/admin/edit_inline/stacked.html
@@ -6,6 +6,7 @@
{% for inline_admin_form in inline_admin_formset %}
{{ inline_admin_formset.opts.verbose_name|title }}:{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}
+ {% if inline_admin_form.admin_url %}{% trans "edit separately" %} {% endif %}
{% if inline_admin_form.show_url %}{% trans "View on site" %}{% endif %}
{% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}{% endif %}