在Django admin中将外键列显示为详细信息对象的链接 [英] Display foreign key columns as link to detail object in Django admin
问题描述
如 link-in-django-admin-to-中所述外键对象,可以显示外键字段作为指向管理详细信息页面的链接。
As explained in link-in-django-admin-to-foreign-key-object, one can display a ForeignKey field as a link to the admin detail page.
总而言之,
class Foo(Model):
bar = models.ForeignKey(Bar)
class FooAdmin(ModelAdmin):
list_display = ('link_to_bar',)
def link_to_bar(self, obj):
link = urlresolvers.reverse('admin:app_bar_change', args=[obj.bar_id])
return u'<a href="%s">%s</a>' % (link, obj.bar) if obj.bar else None
link_to_bar.allow_tags = True
问题是:我们可以更自动地做到吗?例如,向 FooAdmin
定义提供一个外键列表,以显示为指向详细信息页面的链接:
The question is: can we do it more automatically? For instance, provide to the FooAdmin
definition a list of foreign key to display as links to detail page:
class FooAdmin(ModelAdmin):
...
list_foreign_key_links = ('bar',)
...
我知道这些 ModelAdmin
类是通过元类编程生成的。然后,应该有可能。这样做的一个好开始是什么?
I know that these ModelAdmin
classes are generated with metaclass programming. Then, it should be possible. What would be a good start to do so?
推荐答案
以下解决方案使用此答案
,但可在所有模型中重用,避免了向每个管理类添加方法的需要。
The solution below uses this answer but makes it reusable by all models, avoiding the need to add methods to each admin class.
# models.py
from django.db import models
class Country(models.Model):
name = models.CharField(max_length=200)
population = models.IntegerField()
class Career(models.Model):
name = models.CharField(max_length=200)
average_salary = models.IntegerField()
class Person(models.Model):
name = models.CharField(max_length=200)
age = models.IntegerField()
country = models.ForeignKey(Country, on_delete=models.CASCADE)
career = models.ForeignKey(Career, on_delete=models.CASCADE)
示例管理员
# admin.py
from django.utils.html import format_html
from django.urls import reverse
from .models import Person
def linkify(field_name):
"""
Converts a foreign key value into clickable links.
If field_name is 'parent', link text will be str(obj.parent)
Link will be admin url for the admin url for obj.parent.id:change
"""
def _linkify(obj):
linked_obj = getattr(obj, field_name)
if linked_obj is None:
return '-'
app_label = linked_obj._meta.app_label
model_name = linked_obj._meta.model_name
view_name = f'admin:{app_label}_{model_name}_change'
link_url = reverse(view_name, args=[linked_obj.pk])
return format_html('<a href="{}">{}</a>', link_url, linked_obj)
_linkify.short_description = field_name # Sets column name
return _linkify
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
list_display = [
"name",
"age",
linkify(field_name="country"),
linkify(field_name="career"),
]
结果
给出一个名为<$ c的应用程序$ c> app 和一个Person实例具有国家和职业外键值且ID为
123
和 456 <的人(姓名=亚当年龄= 20)
/ code>,
的列表结果将是:
Results
Given an App named app
, and a Person instance Person(name='Adam' age=20)
with country and carreer foreign key values with ids 123
and 456
,
the list result will be:
| Name | Age | Country |...|
|------|-----|-----------------------------------------------------------|...|
| Adam | 20 | <a href="/admin/app/country/123">Country object(123)</a> |...|
(继续)
|...| Career |
|---|---------------------------------------------------------|
|...| <a href="/admin/app/career/456">Career object(456)</a> |
这篇关于在Django admin中将外键列显示为详细信息对象的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!