[Django]-Adding links to full change forms for inline items in django admin?

11πŸ‘

βœ…

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)

138πŸ‘

There is a property called show_change_link since Django 1.8.

52πŸ‘

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',)

31πŸ‘

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:

tabular inline using show_change_link

3πŸ‘

Quentin’s answer above works, but you also need to specify fields = (β€˜admin_link’,)

2πŸ‘

There is a module for this purpose. Check out:
django-relatives

0πŸ‘

I think: args=[instance.id] should be args=[instance.pk]. It worked for me!

Leave a comment