基于列表显示中的自定义可调用在 Django Admin 中排序

Posted

技术标签:

【中文标题】基于列表显示中的自定义可调用在 Django Admin 中排序【英文标题】:Ordering in Django Admin based on a custom callable in list display 【发布时间】:2012-10-20 05:26:12 【问题描述】:

我的列表显示中有一个自定义可调用对象。我希望能够按它排序,但它不对应单个字段,所以我不能单独使用admin_order_field

如果它被选为字段,我希望能够改变查询集的顺序以反映这一点。但是,看起来ChangeList 视图调用get_ordering 通过模型管理员的get_ordering 调用运行它,然后循环遍历给定的排序字段(格式为a.b.c.etc.y.z,其中、b、c等都是与显示列表中的一个或多个字段对应的整数。

在此示例中,我有一个订单页面,其中客户可以是公司/组织个人。我希望能够对其进行排序,以便首先列出人员的所有订单,然后是组织,并且全部按字母顺序排列。

让我们以这个模型管理员设置为例:

class OrderAdmin(models.ModelAdmin):
    list_display = ('pk', 'date_ordered', 'customer')

    def customer(self, obj):
        return obj.organization or "%s %s" % (obj.first_name, obj.last_name)

目前,我无法排序,因为只有当可调用对象附加了 admin_order_field 时,排序字段才可用:

    def customer(self, obj):
        return obj.organization or "%s %s" % (obj.first_name, obj.last_name)
    customer.admin_order_field = 'customer'

问题是,理想情况下,我希望能够截取默认代码并说,“如果其中一个字段是‘客户’,则从列表中删除该字段,而是使用["organization", "last_name", "first_name"] 对其进行排序”。但据我所知,没有办法做到这一点。

我怀疑extra(select='customer':...) 会起作用,除了我使用的是django-pyodbc,因为这是一个 SQL Server 数据库,生成的 SQL 根本不起作用并引发错误:

SELECT * 
FROM   (SELECT 

                ( COALESCE(organization, firstname + ' ' + lastname) ) AS [customer], 
                ..., 
               ( Row_number() 
                   OVER ( 
                     ORDER BY [customer] ASC, [orders].[date_created] DESC, 
                   [orders].[order_id] ASC 
                   ) )                                                    AS 
               [rn] 
        FROM   [orders]) AS X 
WHERE  X.rn BETWEEN 1 AND 100 

错误是:

列名“客户”无效。

重写 django-pyodbc,使用 .extra 不是解决方案。

所以我想知道是否还有什么可以做的,或者我是否必须放弃单独使用客户名称作为排序字段,并将其替换为单独的组织、姓氏和名字列。

【问题讨论】:

【参考方案1】:

请注意,admin_order_field 是 SQL 结果集中的一个字段。因此,您需要做的是在 admin 中覆盖 get_queryset,这样您就有了一个适用于您的排序的“字段”。

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_queryset

您可能还需要 Q() 和 F() 函数。我不知道他们是否在pyodbc中工作。

现在,这个“客户”字段应该只用于排序。它可以通过 obj.customer 访问。

然后你需要一个在那个字段上排序的函数(它也可以称为“客户”)。并在其中执行您想要使用 COALESCE 执行的逻辑。

【讨论】:

是的,正如我的问题中所述,不幸的是,仅在 get_queryset 中使用 .extra 将不起作用。据我所知,这个问题从来没有解决方案。我想为ModelAdmin 类创建一个包装器,它允许admin_order_field 是可迭代的,并且单个字段名称可能会起作用。

以上是关于基于列表显示中的自定义可调用在 Django Admin 中排序的主要内容,如果未能解决你的问题,请参考以下文章

`Django 管理`到项目模板中的自定义标题

Django admin 中的自定义相关下拉菜单

Django:如何查看已定义的自定义标签?

iOS中的自定义“可调整大小的图像”绘图

Django 1.3 或更低版本的 Django Admin 中的自定义过滤器

剑道网格“每页项目”下拉列表中的自定义值