Изменить ссылку на страницу изменения внешнего ключа

При просмотре списка изменений администратора для модели можно ли сделать столбцы, соответствующие внешним ключам, ссылки на их соответствующие страницы? Простой пример: у меня есть объект Foo, который содержит Bar как внешний ключ. Если я просмотрю список изменений администратора для Foo (и включил его в Bar в столбцах display_list), главный столбец будет ссылаться на страницу редактирования экземпляра Foo, в то время как столбец Bar будет ссылаться на страницу редактирования экземпляра Boo. Я понимаю, что могу переопределить используемый шаблон, но мне было любопытно, было ли решение, которое не требовало этого.

Ответы

Ответ 1

Вы можете определить пользовательский метод для использования в списке изменений, который возвращает 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 

Ответ 2

Я нашел и понравился Даниэлю, хотя вариант изменения списков отменяет все изменения, которые вы уже сделали. Таким образом, это способ исправить это:

Сначала вам нужно получить ссылку на запрос, вы можете сделать это, обернув 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

Это даст вам фильтр внутри строк списка изменений. Я ответил на это в другом вопросе, но это было то место, на котором я действительно был первым, поэтому хотел записать его здесь.: -)