在子管理员中显示父字段 (list_display)

Posted

技术标签:

【中文标题】在子管理员中显示父字段 (list_display)【英文标题】:Display parent fields in childs admin (list_display) 【发布时间】:2011-06-19 13:52:09 【问题描述】:

这是models.py的sn-p

class Applicant(models.Model):
    name = models.CharField(...)
    email = models.CharField(...)

class Application(models.Model):
    applicant = models.ForeignKey(Applicant)
    text = models.TextField(...)

这是我的 admin.py:

class ApplicationAdmin(model.ModelAdmin):
    list_display = ['text', *******]

admin.site.register(Application, ApplicationAdmin)

我想在 ApplicationAdmin 中显示申请人的姓名和电子邮件。

在问 SO 之前你尝试过什么? 我查看了以下代码,不起作用

list_display = ['text', 'applicant__name','applicant__email']

我查看了ModelAdmin.inlines,但正如我们所见,父/子关系必须颠倒。

有什么建议吗?如何在应用程序管理员中显示申请人姓名/电子邮件。最好不要使用新字段等迁移数据库。

【问题讨论】:

Can "list_display" in a Django ModelAdmin display attributes of ForeignKey fields?的可能重复 【参考方案1】:

如果只需要在列表中显示:

class Applicant(models.Model):
    name = models.CharField(...)
    email = models.CharField(...)

    def __unicode__(self):
        return "%s <%s>" % (self.name, self.email)

class ApplicationAdmin(model.ModelAdmin):
    list_display = ['text', 'applicant']

回答您的评论

但希望将每个字段作为管理员中的新行/行,而不是字符串。

不确定它是否是最好的解决方案,但它会起作用:

class Application(models.Model):

    @property
    def applicant__name(self):
        return self.applicant.name

    # or maybe:

    def __getattr__(self, name):
        if name.startswith('applicant__'):
            return gettattr(self.applicant, 
                            name[len('applicant__'):])
        raise AttributeError()

class ApplicationAdmin(model.ModelAdmin):
    list_display = ['text', 'applicant__name']

【讨论】:

如果没有其他解决方案,将作为替代方案,但希望将每个字段作为管理员中的新行/行,而不是作为字符串。感谢您的回答,非常感谢。 没有尝试您的“可能”解决方案。但另一个就像一个魅力,即使没有“财产”。【参考方案2】:

您可以像list_display docs 中的第四种可能性一样进行操作。只需向您的应用程序模型添加一个方法,如下所示:

class Application(models.Model):
    applicant = models.ForeignKey(Applicant)
    text = models.TextField(...)

    def applicant_name(self):
        return self.applicant.name
    applicant_name.short_description = 'Applicant Name'

    def applicant_email(self):
        return self.applicant.email
    applicant_email.short_description = 'Applicant Email'

然后您可以像这样设置您的 ModelAdmin:

class ApplicationAdmin(model.ModelAdmin):
    list_display = ['text', 'applicant_name', 'applicant_email']

【讨论】:

是的...在我发布此内容时,已接受的解决方案已被编辑。祝你的模型好运! 这可能是更好的方法 答案很好。但是有人可以告诉在列表显示期间调用申请人名称时实际发生了什么。他们是否为检索申请人名称而进行了单独的数据库调用。 我真的不知道管理员做了什么。要回答这样的问题,django-debug-toolbar 是您的朋友。即使它确实进行了单独的调用,您也可以根据您的用例以某种方式利用select-related 或prefetch-related。

以上是关于在子管理员中显示父字段 (list_display)的主要内容,如果未能解决你的问题,请参考以下文章

在 list_display 中显示内联模型字段

如何允许在 Django 管理员中通过自定义 list_display 字段进行排序,该字段没有 DB 字段,也没有可注释

Django Admin:如何在 oneToOne 关系中的两个模型中显示带有 list_display 的字段值?

通过相关模型上的过滤器对 list_display 字段进行排序

如何在 Django admin 中本地化 list_display 字段?

Django admin list_display 不显示模型方法返回项