У меня есть модель A с ForeignKey для модели B. Как в админке Django добавить ссылку на страницу администратора модели A рядом с полем ForeignKey, открывающим страницу администратора модели B?

38
Laurent 3 Мар 2015 в 16:21

5 ответов

Лучший ответ

Вы можете сделать следующее:

Models.py (пример):

model B(models.Model):
    name = models.CharField(max_length=20)

model A(models.Model):
    field1 = models.CharField(max_length=20)
    Bkey = models.ForeignKey(B)

Admin.py

from django.core import urlresolvers

class AAdmin(admin.ModelAdmin):
    list_display = ["field1","link_to_B"]
    def link_to_B(self, obj):
        link=urlresolvers.reverse("admin:yourapp_b_change", args=[obj.B.id]) #model name has to be lowercase
        return u'<a href="%s">%s</a>' % (link,obj.B.name)
    link_to_B.allow_tags=True

Замените yourapp названием своего приложения.

39
ger.s.brett 5 Июн 2016 в 05:49

Я создал миксин, который делает это + похожее на отношения «многие ко многим» (там он показывает количество связанных объектов и ссылки на список изменений с соответствующим фильтром). Основываясь на сути, я разветвился от:

https://gist.github.com/hovi/2e3a216ecc4be685ec9e0d23b0eb7901

Проверено на django 1.1.x и 1.0.x

0
K.H. 30 Окт 2019 в 15:07

Сегодня есть более простое решение, когда related является полем внешнего ключа, с которым нужно связать:

class YourModelAdmin(model.modelAdmin):
    list_display = ["field_one", "field_two", "related"]
    list_display_links = ["field_one", "related"]
0
keeshux 28 Янв 2019 в 08:57

Django 2.0+ и Python 3.5+:

from django.urls import reverse
from django.utils.html import escape, mark_safe

@admin.register(models.YourModel)
class YourModelAdmin(BaseModelAdmin):
    def model_str(self, obj: models.YourModel):
        link = reverse("admin:module_model_change", args=[obj.model_id])
        return mark_safe(f'<a href="{link}">{escape(obj.model.__str__())}</a>')

    model_str.short_description = 'Model'
    model_str.admin_order_field = 'model' # Make row sortable

    list_display = (
        'model_str',
    )
20
Tobias Ernst 10 Окт 2019 в 19:16

В дополнение к принятому ответу в новых версиях Django метод обратного теперь находится в пакете django.urls (см. эту ссылку ).

Кроме того, вы должны использовать format_html для вывода HTML в админке. Таким образом, allow_tags становятся бесполезными.

Наконец, чтобы добавить ссылку на страницу редактирования пользователя, у меня есть эта функция в admin.py:

from django.urls import reverse
from django.utils.html import format_html


class ObjectAdmin(admin.ModelAdmin):
    list_display = ('name', 'link_to_user')

    def link_to_user(self, obj):
        link = reverse("admin:auth_user_change", args=[obj.user_id])
        return format_html('<a href="{}">Edit {}</a>', link, obj.user.username)
    link_to_user.short_description = 'Edit user'
31
Benbb96 23 Дек 2020 в 14:23