更改列表链接到外键更改页面

时间:2009-09-12 00:18:10

标签: django django-models django-admin

查看模型的管理员更改列表时,是否可以将与外键对应的列链接到其各自的页面?一个简单的例子是我有一个包含Bar作为外键的Foo对象。如果我正在查看Foo的管理员更改列表(并将其设置为在display_list列中包含Bar),则主列将链接到Foo实例的编辑页面,而Bar列将链接到Boo实例的编辑页面。我知道我可以覆盖使用的模板,但我很好奇是否有一个不需要的解决方案。

2 个答案:

答案 0 :(得分:21)

您可以定义要在changelist中使用的自定义方法,该方法返回链接的HTML。

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 

您提出的问题存在一个问题 - 如果Foo有一个Bar的外键,那么每个foo都链接到一个条形码,因此您可以链接到该条的编辑页面。但是,每个栏都链接到多个foos,因此要求链接到“Foo实例的编辑页面”没有意义。您可以做的是链接到Foo的更改列表页面,过滤器设置为仅显示链接到此栏的实例:

    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 :(得分:1)

我发现并喜欢Daniel的答案,尽管更改列表变体会清除您已经完成的任何更改。所以这是解决这个问题的一种方法:

首先,你需要获得对请求的引用,你可以像我一样包装changelist_viewqueryset来做到这一点:

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

这将为您提供更改列表行内的过滤器。我在另一个问题中回答了这个问题,但这是我实际上第一个出现的地方,所以想在这里记录下来。 : - )