Adding links to full change forms for inline items in django admin?
Solution 1
I had similar problem and I came up with custom widget plus some tweaks to model form. Here is the widget:
from django.utils.safestring import mark_safe
class ModelLinkWidget(forms.Widget):
def __init__(self, obj, attrs=None):
self.object = obj
super(ModelLinkWidget, self).__init__(attrs)
def render(self, name, value, attrs=None):
if self.object.pk:
return mark_safe(
u'<a target="_blank" href="../../../%s/%s/%s/">%s</a>' %\
(
self.object._meta.app_label,
self.object._meta.object_name.lower(),
self.object.pk, self.object
)
)
else:
return mark_safe(u'')
Now since widget for each inline need to get different object in constructor you can't just set it in standard way, but in Form's init method:
class TheForm(forms.ModelForm):
...
# required=False is essential cause we don't
# render input tag so there will be no value submitted.
link = forms.CharField(label='link', required=False)
def __init__(self, *args, **kwargs):
super(TheForm, self).__init__(*args, **kwargs)
# instance is always available, it just does or doesn't have pk.
self.fields['link'].widget = ModelLinkWidget(self.instance)
Solution 2
There is a property called show_change_link
since Django 1.8.
Solution 3
I did something like the following in my admin.py:
from django.utils.html import format_html
from django.core.urlresolvers import reverse
class MyModelInline(admin.TabularInline):
model = MyModel
def admin_link(self, instance):
url = reverse('admin:%s_%s_change' % (instance._meta.app_label,
instance._meta.module_name),
args=(instance.id,))
return format_html(u'<a href="{}">Edit</a>', url)
# … or if you want to include other fields:
return format_html(u'<a href="{}">Edit: {}</a>', url, instance.title)
readonly_fields = ('admin_link',)
Solution 4
The currently accepted solution here is good work, but it's out of date.
Since Django 1.3, there is a built-in property called show_change_link = True
that addresses this issue.
This can be added to any StackedInline or TabularInline object. For example:
class ContactListInline(admin.TabularInline):
model = ContactList
fields = ('name', 'description', 'total_contacts',)
readonly_fields = ('name', 'description', 'total_contacts',)
show_change_link = True
The result will be something line this:
Solution 5
Quentin's answer above works, but you also need to specify fields = ('admin_link',)
Related videos on Youtube
David Eyk
Jack of all trades, master of webs. Asking all the wrong questions since I started teaching myself how to program Applesoft Basic in 1988. Continuing the tradition since joining SO in 2009.
Updated on July 09, 2022Comments
-
David Eyk almost 2 years
I have a standard admin change form for an object, with the usual StackedInline forms for a ForeignKey relationship. I would like to be able to link each inline item to its corresponding full-sized change form, as the inline item has inlined items of its own, and I can't nest them.
I've tried everything from custom widgets to custom templates, and can't make anything work. So far, the "solutions" I've seen in the form of snippets just plain don't seem to work for inlines. I'm getting ready to try some DOM hacking with jQuery just to get it working and move on.
I hope I must be missing something very simple, as this seems like such a simple task!
Using Django 1.2.
-
Florian Ledermann almost 12 yearsI found the answer given in stackoverflow.com/questions/2120813 better.
-
maxbellec over 7 yearsDjango >= 1.8, use
show_change_link
stackoverflow.com/a/28170958/3218806
-
-
David Eyk almost 14 yearsI haven't had time to try this, but it looks like it should work. :) Thanks.
-
Shai Berger about 11 yearsThis is a fine solution, it can be made even more fine by combining it with stackoverflow.com/questions/5197280/…
-
Shai Berger about 11 yearsAlso, this may be vulnerable to XSS attacks (depending on the objects presented and where they come from), and you really don't want those in the admin -- render the string with a Django Template instead of python's %.
-
jenny about 11 yearsI've added this to my admin but I do not see the link. The column has been added tho. Any ideas?
-
freb over 10 yearsNice solution. Very clean
-
elsadek almost 10 yearswhen you save the edit form, it should return to the original parent edit page not to the change list of the edited object.
-
Serj Zaharchenko almost 9 yearsIt seems that in Django 1.8 instead of
instance._meta.module_name
it should readinstance._meta.model_name
-
adkl about 6 yearsBut what if I want a title to be a hyperlink, but not a label next to the title?
-
sheikhsalman08 almost 5 yearsTrue module_name should be model_name
-
Scratch'N'Purr over 4 yearsThis solution works, but as noted from some of the other comments, use
instance.pk
instead ofinstance.id
,instance._meta.model_name
instead ofinstance._meta.module_name
, and addadmin_link
to fields, e.gfields = (..., 'admin_link', ...)
-
Joe Sadoski over 2 yearsA quick note that you must register the model in the admin site (not just the inline), or the change link simply doesn't display above the inline (Django 3.2).