Django admin:从反向 FK 聚合中排序 list_display 字段

Posted

技术标签:

【中文标题】Django admin:从反向 FK 聚合中排序 list_display 字段【英文标题】:Django admin: SORTING list_display field from reverse FK aggregation 【发布时间】:2017-09-02 20:41:51 【问题描述】:

模型 Station 具有到 System 的 FK。我想将 Station 计数显示为 System 管理员更改列表中的一列。我已经使用下面的代码实现了这一点,但我很难使“num_stations”列可排序。

模型.py:

class System(models.Model):
    pass

class Station(models.Model):
   system_info = models.ForeignKey(System)

admin.py:

class SystemAdmin(admin.ModelAdmin):
    def num_stations(self, obj):
        return obj.station_set.count()

    # num_stations.admin_order_field = ????
    num_stations.short_description = 'stations'

    list_display = (num_stations',)

反向关系的普通“station_set”语法似乎在 admin_order_field 中不起作用,尽管其他堆栈溢出问题通常显示支持正向遍历关系 例如

Django admin: how to sort by one of the custom list_display fields that has no database field Can “list_display” in a Django ModelAdmin display attributes of ForeignKey fields?。

【问题讨论】:

您链接到的question 包含答案。您需要覆盖查询集并注释计数。不可能使用admin_order_field 来引用station_set.count(),即使是这样,对查询集中的每个项目进行计数而不是注释的效率也会降低。 【参考方案1】:

感谢Alasdair 的评论,正如所指出的,答案在this question 中。这是适合我的问题的解决方案:

class SystemAdmin(admin.ModelAdmin):
    def num_stations(self, obj):
        return obj.num_stations

    def get_queryset(self, request):
        # def queryset(self, request): # For Django <1.6
        qs = super(SystemAdmin, self).get_queryset(request)
        # qs = super(CustomerAdmin, self).queryset(request) # For Django <1.6
        qs = qs.annotate(num_stations=Count('station'))
        return qs

    num_stations.admin_order_field = 'num_stations'
    num_stations.short_description = 'stations'

    list_display = ('num_stations', )

【讨论】:

以上是关于Django admin:从反向 FK 聚合中排序 list_display 字段的主要内容,如果未能解决你的问题,请参考以下文章

如何防止在 Django Admin 中对 FK / MTM 字段进行自我(递归)选择

Django Admin Cookbook-35如何使用带有大量对象的FK管理模型

Django中日期时间字段之间的聚合差异

从 django admin 重新排序导航栏

模板标签和反向函数中的 django admin 冒号语法

django上课笔记5