Gui*_*mas 2 python django django-admin
如link-in-django-admin-to-foreign-key-object中所述,可以显示ForeignKey字段作为管理详细信息页面的链接.
总结一下,
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
Run Code Online (Sandbox Code Playgroud)
问题是:我们可以更自动地做到吗?例如,向FooAdmin定义提供要显示为详细信息页面链接的外键列表:
class FooAdmin(ModelAdmin):
...
list_foreign_key_links = ('bar',)
...
Run Code Online (Sandbox Code Playgroud)
我知道这些ModelAdmin类是使用元类编程生成的.那么,它应该是可能的.这样做有什么好的开始?
gta*_*ico 14
下面的解决方案使用了这个答案, 但是它可以被所有模型重用,避免了为每个管理类添加方法的需要.
# 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)
Run Code Online (Sandbox Code Playgroud)
# 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):
app_label = obj._meta.app_label
linked_obj = getattr(obj, field_name)
model_name = linked_obj._meta.model_name
view_name = f"admin:{app_label}_{model_name}_change"
link_url = reverse(view_name, args=[linked_obj.id])
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"),
]
Run Code Online (Sandbox Code Playgroud)
给定一个名为App的应用程序app,以及一个Person(name='Adam' age=20)带有id 123和country和carreer外键值的Person实例456,列表结果将为:
| Name | Age | Country |...|
|------|-----|-----------------------------------------------------------|...|
| Adam | 20 | <a href="/admin/app/country/123">Country object(123)</a> |...|
Run Code Online (Sandbox Code Playgroud)
(继续)
|...| Career |
|---|---------------------------------------------------------|
|...| <a href="/admin/app/career/456">Career object(456)</a> |
Run Code Online (Sandbox Code Playgroud)
BaseModelAdmin一个好的开始是查看和的来源ModelAdmin。尝试找出 ModelAdmin 如何生成默认链接。扩展ModelAdmin,添加一个方法来生成任意外键的链接,并查看如何ChangeList生成更改列表。
我还建议您使用format_html来呈现链接,这使得link_to_bar.allow_tags = True不必要:
from django.utils.html import format_html
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 format_html('<a href="{}">{}</a>', link, obj.bar) if obj.bar else None
Run Code Online (Sandbox Code Playgroud)