[Fixed]-Change list link to foreign key change page

21👍

You can define a custom method to use in the changelist which returns the HTML of the link.

from django.core.urlresolvers import reverse

class MyFooAdmin(admin.ModelAdmin):
    list_display = ('foo', 'bar_link')

    def bar_link(self, obj):
        url = reverse('admin:myapp_bar_change', args=(obj.pk,))
        return '<a href="%s">Edit Bar</a>' % url 
    bar_link.allow_tags = True 

One problem with your question as stated – if Foo has a foreign key to Bar, then each foo links to a single bar, so you can link to the edit page for that bar. However, each bar links to multiple foos, so it doesn’t make sense to ask for a link to ‘the Foo instance’s edit page’. What you can do is link to the changelist page for Foo with the filter set to only show the instances that link to this Bar:

    def foo_link(self, obj):
        url = reverse('admin:myapp_foo_changelist')
        return '<a href="%s?bar=%s">See Foos</a>' % (url, obj.pk) 
    foo_link.allow_tags = True 

1👍

I found and liked Daniel’s answer, although the changelist variant clears away any changes you’ve already done. So this is a way to fix that:

First you need to get a reference to the request, you can do that by wrapping changelist_view or queryset as I did:

class CountryAdmin(ModelAdmin):
    model = Country
    list_display = ('pk', 'continent_changelist')

    # ...

    def queryset(self, request):
        self._get_params = request.GET
        return super(CountryAdmin, self).queryset(request)

    def continent_changelist(self, obj):
        url = reverse('admin:yourapp_country_changelist')
        querystring = self._get_params.copy()
        querystring['continent__id__exact'] = obj.continent.pk
        return u'<a href="{0}?{1}">{2}</a>'.format(
            url, querystring.urlencode(), obj.continent)
    continent_changelist.allow_tags = True

That will give you a filter inside the changelist rows. I answered this in another question, but this was the place I actually came first, so wanted to record it here. 🙂

Leave a comment