假设我有一个Book模型,其中包含Publisher模型的外键。
我如何在Django管理员中显示每个发布者发布的图书数量的列,我可以使用内置排序?
答案 0 :(得分:75)
我有同样的问题(我无法更改模型的管理器以添加缓慢的注释或连接)。这里有两个答案的组合。 @Andre非常接近,Django Admin支持仅修改admin的查询集,因此在此处应用相同的逻辑,然后使用admin_order_field属性。当然,您仍然需要将新的管理字段添加到list_display。
from django.db.models import Count
class EventAdmin(admin.ModelAdmin)
list_display = (..., 'show_artist_count')
def queryset(self, request):
# def get_queryset(self, request): for Django 1.6+
qs = super(EventAdmin, self).queryset(request)
return qs.annotate(artist_count=Count('artists'))
def show_artist_count(self, inst):
return inst.artist_count
show_artist_count.admin_order_field = 'artist_count'
答案 1 :(得分:8)
试试这个:
制作一个新的Manager(和aggregate并计算图书关系字段的数量):
class PublisherManager(models.Manager):
def get_query_set(self):
return super(PublisherManager,self).get_query_set().annotate(pubcount=Count('book'))
在pubcount
上对其进行排序:
class Publisher(models.Model):
......
objects = PublisherManager()
class Meta:
ordering = ('pubcount',)
答案 2 :(得分:1)
你应该开始添加:
class PublisherManager(models.Manager):
def get_query_set(self):
return super(PublisherManager,self).get_query_set().annotate(pubcount=Count('book'))
但是将其添加为可排序字段的正确方法是:
class Publisher(models.Model):
......
objects = PublisherManager()
def count(self):
return self.pubcount
count.admin_order_field = 'pubcount'
然后你可以在admin.py
中将'count'添加到model admin的list_display属性中答案 3 :(得分:0)
尝试这样的事情:
class PublisherAdminWithCount(Admin):
def book_count(self, obj):
return obj.book_set.count()
list_display = ('user_count',)
admin.site.register(Group, PublisherAdminWithCount)
答案 4 :(得分:0)
林肯B的答案对我来说是正确的方式。
起初我只想评论他的解决方案,但实际上我发现自己解决了一个稍微不同的问题。我有一个管理类,我想“自定义”我的需求 - 即django-taggit
管理员。在我的一个应用程序admin.py
中,我添加了:
# sort tags by name in admin (count items also possible)
from taggit.admin import TagAdmin
TagAdmin.ordering = ["name"]
# make sortable on item_count:
# 1. function for lookup
def item_count(obj):
"""This takes the item_count from object: didn't work as model field."""
return obj.item_count # not needed: obj.taggit_taggeditem_items.count()
# 2. property in function - admin field name
item_count.admin_order_field = 'item_count'
# 3. queryset override, with count annotation
from django.db.models import Count
TagAdmin.queryset = lambda self, request: super(TagAdmin, self).queryset(request).annotate(item_count=Count('taggit_taggeditem_items'))
# 4. add to list display
TagAdmin.list_display = ["name", item_count]
对我来说有趣的观察是,我不能只注释queryset
,并将"item_count"
添加到list_display
- 因为item_count
中没有TagAdmin
方法1}},也不是Tag
模型类中的方法或字段(仅限于queryset
)。