Django Admin list_display 添加列[统计相关ForeignKey的记录]
Posted
技术标签:
【中文标题】Django Admin list_display 添加列[统计相关ForeignKey的记录]【英文标题】:Django Admin list_display add column [count records of related ForeignKey] 【发布时间】:2017-04-09 09:25:34 【问题描述】:我是 Python 和 Django 的新手。
我试图计算模型的外键项/记录,并将其显示为 Admin list_display 中的一列。
所以我有一个模型“作者”,作为模型“书”的外键。
这是models.py:
class Author(models.Model):
name = models.CharField(
max_length=100,
)
class Meta:
ordering = ['-name ']
verbose_name = _('Author')
verbose_name_plural = _('Authors')
def __str__(self):
return self.author
@models.permalink
def get_absolute_url(self):
return reverse('author_detail', kwargs='pk': self.pk)
class Book(models.Model):
author = models.ForeignKey(
'Author',
related_name='menu_items',
verbose_name=_('author'),
)
bookname= models.CharField(
max_length=100,
)
publisher= models.CharField(
max_length=100,
)
class Meta:
ordering = ['-bookname']
verbose_name = _('Book')
verbose_name_plural = _('Books')
def __str__(self):
return self.bookname
@models.permalink
def get_absolute_url(self):
return ('book_detail', [self.pk])
这是 admin.py
from django.contrib import admin
from .models import Author, Book
class BookInline(admin.TabularInline):
model = Book
extra = 1
@admin.register(Author)
class LibraryAdmin(admin.ModelAdmin):
def NumberOfBooks(self, obj):
#I guess sth is wrong here when trying to count the book_set
return obj.book_set.count()
NumberOfBooks.short_description = "Books Count"
list_display = ['bookname', 'publisher', 'NumberOfBooks']
inlines = [BookInline]
我想统计每个作者写了多少本书,并在管理页面的第二级显示如下Home>Authors>Author:
Author | Books Count
Someone1 NumberOfBooks
Someone2 NumberOfBooks
Someone3 NumberOfBooks
Someone4 NumberOfBooks
但是我得到了错误:
'Author' object has no attribute 'book_set'
1.我做错了 obj.book_set.count() 吗?
我以为obj.book_set
会引用同一个“作者”(obj)下的“书”,听起来我误解了它,但我不确定如何实现我的意图。
2。相反,如果我想在“作者”中添加一个字段,该字段将自动计算与每个作者相关的“书”的数量,这应该是一种更好的方法吗?该怎么做?
【问题讨论】:
【参考方案1】:错误页面上应该有一个包含所有可用字段的列表,并且您应该找到一个名为 menu_items
的字段(这就是您在 Book
模型中放入 related_name
的内容)。
但这可能不是最好的选择。您应该能够像这样覆盖 LibraryAdmin(admin.ModelAdmin)
类上的 get_queryset()
方法:
...
from django.db.models import Count
...
@admin.register(Loan)
class LibraryAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(LibraryAdmin, self).get_queryset(request)
return qs.annotate(books_count=Count('menu_items'))
def books_count(self, inst):
return inst.books_count
list_display = ['bookname', 'publisher', 'books_count']
inlines = [BookInline]
这样计数将由您的数据库完成。
【讨论】:
` ERRORS:@admin.register(Loan)
应该是@admin.register(Author)
,我打错了,但这不是问题所在,例如,我改变了名称稍微便于理解。
我终于通过添加:def show_books_count(self, inst): return inst.books_count list_display = ['bookname', 'publisher', 'show_books_count']
得到了这项工作,但你能解释一下为什么这样做以及(self, inst)
是做什么的吗?可以简化并添加到def get_queryset
吗?
你得到了那个错误,因为 books_count
模型类中缺少 Admin
属性,确实,我错过了像你这样的方法。 inst
是一个具体的对象,它有一个 books_count
属性,因为我们 annotate()
d 查询集。
@GregKaleka 在Book
模型上有一个related_name='menu_items'
。这就是为什么这里应该是qs.annotate(books_count=Count('menu_items'))
。以上是关于Django Admin list_display 添加列[统计相关ForeignKey的记录]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django admin 中本地化 list_display 字段?
Django admin list_display 在鼠标悬停时显示全文
如何忽略在 django admin list_display 中加载巨大的字段?
Django admin:从反向 FK 聚合中排序 list_display 字段