我有一个Person模型,它与Book有外键关系,Book有许多字段,但我最关心的是author(一个标准CharField)。

话虽如此,在我的PersonAdmin模型中,我想显示book。作者使用list_display:

class PersonAdmin(admin.ModelAdmin):
    list_display = ['book.author',]

我已经尝试了所有显而易见的方法,但似乎都不起作用。

有什么建议吗?


当前回答

如果你尝试在内联,你不会成功,除非:

在内联中:

class AddInline(admin.TabularInline):
    readonly_fields = ['localname',]
    model = MyModel
    fields = ('localname',)

在你的模型(MyModel):

class MyModel(models.Model):
    localization = models.ForeignKey(Localizations)

    def localname(self):
        return self.localization.name

其他回答

如果你尝试在内联,你不会成功,除非:

在内联中:

class AddInline(admin.TabularInline):
    readonly_fields = ['localname',]
    model = MyModel
    fields = ('localname',)

在你的模型(MyModel):

class MyModel(models.Model):
    localization = models.ForeignKey(Localizations)

    def localname(self):
        return self.localization.name

和其他人一样,我也选择了可调用对象。但它们有一个缺点:默认情况下,你不能在上面点餐。幸运的是,有一个解决方案:

姜戈 >= 1.8

def author(self, obj):
    return obj.book.author
author.admin_order_field  = 'book__author'

Django < 1.8

def author(self):
    return self.book.author
author.admin_order_field  = 'book__author'

这个答案已经被接受了,但如果还有其他傻瓜(比如我)没有立即从目前接受的答案中得到它,这里有更多的细节。

ForeignKey引用的模型类需要有一个__unicode__方法,如下所示:

class Category(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

这对我来说很重要,也适用于上述情况。这适用于Django 1.0.2。

请注意,添加get_author函数会减慢管理中的list_display,因为显示每个人会产生SQL查询。

为了避免这种情况,您需要修改PersonAdmin中的get_queryset方法,例如:

def get_queryset(self, request):
    return super(PersonAdmin,self).get_queryset(request).select_related('book')

之前:36.02ms内73个查询(管理中67个重复查询) 之后:10.81ms内查询6次

在PyPI中有一个非常容易使用的包可以处理这个问题:django-related-admin。你也可以在GitHub中看到代码。

使用它,你想要达到的效果很简单:

class PersonAdmin(RelatedFieldAdmin):
    list_display = ['book__author',]

这两个链接都包含了安装和使用的全部细节,所以我不会把它们粘贴在这里,以防它们发生变化。

顺便说一句,如果你已经在使用模型以外的东西。Admin(例如,我使用的是SimpleHistoryAdmin代替),你可以这样做:类MyAdmin(SimpleHistoryAdmin, RelatedFieldAdmin)。