代码之家  ›  专栏  ›  技术社区  ›  Adam

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

  •  15
  • Adam  · 技术社区  · 15 年前

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

    2 回复  |  直到 11 年前
        1
  •  21
  •   Daniel Roseman    15 年前

    您可以定义一个自定义方法,用于返回链接的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有一个外键to bar,那么每个foo链接到一个单独的bar,这样您就可以链接到该bar的编辑页。但是,每个栏链接到多个foo,因此要求链接到“foo实例的编辑页”是没有意义的。您可以通过设置为仅显示链接到此栏的实例的过滤器链接到foo的changelist页面:

        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 
    
        2
  •  1
  •   odinho - Velmont    11 年前

    我发现并喜欢丹尼尔的答案,尽管这个变更列表变体可以清除您已经做过的任何更改。所以这是一种解决方法:

    首先,您需要获得对请求的引用,您可以通过包装 changelist_view queryset 正如我所做的:

    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
    

    这将在changelist行中为您提供一个过滤器。我在另一个问题中回答了这个问题,但这是我第一个来到的地方,所以我想把它记录在这里。-)