Изменить список ссылок на страницу изменения внешнего ключа
-
06-07-2019 - |
Вопрос
При просмотре списка изменений администратора для модели можно ли сделать столбцы, соответствующие внешним ключам, ссылками на соответствующие страницы? Простой пример - у меня есть объект Foo, который содержит Bar в качестве внешнего ключа. Если я просматриваю список изменений администратора для Foo (и для него установлено включение Bar в столбцах display_list), основной столбец будет ссылаться на страницу редактирования экземпляра Foo, а столбец Bar - на страницу редактирования экземпляра Boo. Я понимаю, что могу переопределить используемый шаблон, но мне было любопытно, если бы было решение, которое не требовало этого.
Решение
Вы можете определить собственный метод для использования в списке изменений, который возвращает 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
Другие советы
Мне понравился ответ Даниэля, хотя вариант списка изменений удаляет все изменения, которые вы уже сделали. Так что это способ исправить это:
Сначала вам нужно получить ссылку на запрос, вы можете сделать это, обернув 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
Это даст вам фильтр внутри строк списка изменений. Я ответил на это в другом вопросе, но это было то место, куда я пришел первым, поэтому хотел записать это здесь. : -)