如何将可排序的计数列添加到具有多对一关系的模型的Django管理员?

GJ.*_*GJ. 49 django django-models django-admin

假设我有一个Book模型,其中包含Publisher模型的外键.

我如何在Django管理员中显示每个发布者发布的图书数量的列,我可以使用内置排序?

Lin*_*n B 78

我遇到了同样的问题(我无法更改模型的管理器以添加缓慢的注释或连接).这里有两个答案的组合.@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'
Run Code Online (Sandbox Code Playgroud)

  • [自Django 1.6](https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_queryset),ModelAdmin方法名为**get_queryset**而不是****查询集. (12认同)
  • 别忘了添加这一行:来自django.db.models import Count (4认同)
  • `queryset` 在 Django 1.6+ 中调用 `super()` 时也变成了 `get_queryset`:`qs = super(EventAdmin, self).get_queryset(request)` (3认同)
  • 无论如何将它设置为默认排序方法?例如,ordering =('artist_count').对于我来说失败的领域不存在. (2认同)
  • 它适用于初始加载,但如果我搜索对象,在匹配结果上它会给出错误的计数。不知道它是如何得出一些奇怪的数字的。 (2认同)

And*_*ard 8

试试这个:

创建一个新的经理(并在书籍关系字段中聚合计数):

class PublisherManager(models.Manager):
    def get_query_set(self):
        return super(PublisherManager,self).get_query_set().annotate(pubcount=Count('book'))
Run Code Online (Sandbox Code Playgroud)

排序pubcount:

class Publisher(models.Model):
    ......
    objects = PublisherManager()

    class Meta:
        ordering = ('pubcount',)
Run Code Online (Sandbox Code Playgroud)

  • @stevejalim,没错.如果计数器不必是"实时",你也可以在发布者身上有一个book_count字段,并在保存书籍时用信号更新它..... (2认同)