当前位置:  开发笔记 > 编程语言 > 正文

Django ModelAdmin中的"list_display"可以显示ForeignKey字段的属性吗?

如何解决《DjangoModelAdmin中的"list_display"可以显示ForeignKey字段的属性吗?》经验,为你挑选了8个好方法。

我有一个与Book有外键关系的Person模型.本书有很多领域,但我最关心的是"作者"(标准的CharField).

话虽如此,在我的PersonAdmin模型中,我想使用"list_display"显示"book.author".我已经尝试了所有这些明显的方法(见下文),但似乎没有任何效果.有什么建议?

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

imjoevasquez.. 444

作为另一种选择,您可以查找如下:

class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')

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


Will.. 131

尽管上面有很多很好的答案,而且由于我是Django的新手,我还是被困住了.这是我从一个非常新手的角度来解释的.

models.py

class Author(models.Model):
    name = models.CharField(max_length=255)

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=255)

admin.py(错误的方式) - 你认为它可以通过使用'model__field'来引用,但事实并非如此

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'author__name', ]

admin.site.register(Book, BookAdmin)

admin.py(正确的方法) - 这是你如何引用Django方式的外键名称

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'get_name', ]

    def get_name(self, obj):
        return obj.author.name
    get_name.admin_order_field  = 'author'  #Allows column order sorting
    get_name.short_description = 'Author Name'  #Renames column head

    #Filtering on side - for some reason, this works
    #list_filter = ['title', 'author__name']

admin.site.register(Book, BookAdmin)

有关其他参考,请参阅此处的Django模型链接



1> imjoevasquez..:

作为另一种选择,您可以查找如下:

class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')

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



2> Will..:

尽管上面有很多很好的答案,而且由于我是Django的新手,我还是被困住了.这是我从一个非常新手的角度来解释的.

models.py

class Author(models.Model):
    name = models.CharField(max_length=255)

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=255)

admin.py(错误的方式) - 你认为它可以通过使用'model__field'来引用,但事实并非如此

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'author__name', ]

admin.site.register(Book, BookAdmin)

admin.py(正确的方法) - 这是你如何引用Django方式的外键名称

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'get_name', ]

    def get_name(self, obj):
        return obj.author.name
    get_name.admin_order_field  = 'author'  #Allows column order sorting
    get_name.short_description = 'Author Name'  #Renames column head

    #Filtering on side - for some reason, this works
    #list_filter = ['title', 'author__name']

admin.site.register(Book, BookAdmin)

有关其他参考,请参阅此处的Django模型链接


对于订单字段不应该是='author__name'?
这很完美,但是我不确定为什么。obj是BookAdmin吗?

3> Arjen..:

和其他人一样,我也跟着咔嚓声.但他们有一个缺点:默认情况下,你不能订购它们.幸运的是,有一个解决方案:

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



4> Hunger..:

请注意,添加该get_author函数会减慢admin中的list_display,因为显示每个人都会进行SQL查询.

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

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

之前:36.02ms中的73个查询(管理员中有67个重复查询)

之后:在10.81ms内进行6次查询


这真的很重要,应该始终执行

5> Jonny Buchan..:

根据文档,您只能显示__unicode__ForeignKey 的表示形式:

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#list-display

奇怪的是它不支持'book__author'在DB API中的其他地方使用的样式格式.

原来这个功能的票证被标记为"无法修复".


@Mermoz真的吗?看来票证仍然设置为wontfix.它似乎也不起作用(Django 1.3)

6> 小智..:

您可以使用callable在列表显示中显示您想要的任何内容.它看起来像这样:


def book_author(object):
  return object.book.author

class PersonAdmin(admin.ModelAdmin):
  list_display = [book_author,]


这个问题是最终完成的SQL查询量.对于列表中的每个对象,它将进行查询.这就是'field__attribute'非常方便的原因,因为当然Django只会跨越一个SQL查询.奇怪的是,这已经没有了.

7> Jack Cushman..:

我刚刚发布了一个片段,使admin.ModelAdmin支持'__'语法:

http://djangosnippets.org/snippets/2887/

所以你可以这样做:

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

这基本上只是做其他答案中描述的相同的事情,但它自动处理(1)设置admin_order_field(2)设置short_description和(3)修改查询集以避免每行的数据库命中.



8> 小智..:

这个已经被接受了,但如果还有其他的假人(像我一样)没有立即从目前接受的答案中得到它,这里有更多的细节.

ForeignKey需要在其中引用__unicode__方法引用的模型类,如下所示:

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

    def __unicode__(self):
        return self.name

这对我来说有所不同,应该适用于上述场景.这适用于Django 1.0.2.


在python 3上,这将是`def __str __(self):`.
推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有